在Python中,我缺少了从长到宽的自发和容易的转换,反之亦然。
想象一下,我有一个很大的tidy数据框,其中有很多属性列,还有一个包含所有实际值的列,比如
PropA ... PropZ Value
green Saturn 400
green Venus 3
red Venus 2
.
.
通过保持数据的整洁,可以很好地处理数据本身。但有时我必须对某些属性执行一些操作(例如,比较beeing red和beeing green(对于所有与w.r.t其他属性相似的项)可能会很有趣)。
所以,最直接的方法就是尽可能保持它的整洁,只把我感兴趣的某个属性弄乱(PropA)。随后,我可以用我想要的任何函数执行一个行映射,我可以创建一个包含函数ouut的额外PropA条目。
然而,在Python中保持所有其他属性的整洁并不像我使用R所习惯的那样容易,原因是,所有不关键的属性都被我找到的所有pd方法交给了索引。如果我还想保留一些专栏的话,那真是一团糟。
那你怎么处理这个问题呢。有没有别的方法来处理这些问题呢?
我自己也写了一个传播方法,但是速度太慢了。也许,你有一些我可以改进的想法。
#the idea is to group by the remaining properties, which should be left in the long format.
#then i spread the small tidy data table for any group
@staticmethod
def spread(df, propcol, valcol):
def flip(data,pc,vc):
data = data.reset_index(drop=True)
return {data[pc][i]:[data[vc][i]] for i in range(0,len(data))}
#index columns are all which are not affected
indcols = list(df.columns)
indcols.remove(propcol)
indcols.remove(valcol)
tmpdf=pd.DataFrame()
for key, group in df.groupby(indcols):
dc1 = {a:[b] for (a,b) in zip(indcols,key)}
dc2 = flip(group,propcol,valcol)
tmpdf = pd.concat([tmpdf,pd.concat([pd.DataFrame(dc1),pd.DataFrame(dc2)],axis=1)])
return tmpdf.reset_index(drop = True)
最佳答案
在提示的帮助下,我创建了一个更简单的版本。
我对指数机制还是有点困惑,但时间会帮助我更好地理解。
def spread(df, propcol, valcol):
indcol = list(df.columns.drop(valcol))
df = df.set_index(indcol).unstack(propcol).reset_index()
df.columns = [i[1] if i[0] == valcol else i[0] for i in df.columns]
return df