2017-07-20 35 views
2

我错过了在Python中从长到宽,反之亦然的自发和轻松转换。 想象一下,我有一个大的整洁数据帧有很多财产列,并且包含了所有像python pandas pivot:如何做适当的tidyr-like传播?

PropA ... PropZ Value 
green  Saturn 400 
green  Venus 3 
red  Venus 2 
. 
. 

数据本身的实际价值是非常漂亮,通过保持其整洁处理一列。但有时我必须在某些属性上执行某些操作(例如,比较红色和绿色的beeing(对于所有与其他属性相似的项目))。 因此,直接的方法是尽可能保持整洁,只有凌乱的我感兴趣的某些财产(PropA)。随后,我可以使用我希望的任何功能执行行式映射,并且可以创建包含函数输出的额外PropA-Entry。

但是,保持所有其他属性整洁在Python中并不像我以前使用过的那样容易。原因是,所有不重要的属性都通过所有我找到的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) 
+0

多索引不足吗?有一个合理的解释[这里](https://stackoverflow.com/questions/35414625/pandas-how-to-run-a-pivot-with-a-multi-index) – asongtoruin

+0

thx为链接。那么这意味着:通过分层索引来组织整洁的数据会更好吗?因此,我应该通过将所有属性传递给索引并仅保留值列来整理所有数据。但这似乎有点不方便,因为大部分信息都在索引中被捕获。此外,我的属性是可交换的,而不是真正的等级。 – Antalagor

回答

1

借助提示,我创建了一个更简单的版本。 我对索引机制仍然有点困惑,但时间会帮助我更好地理解。

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