在保持数据帧的一部分的同时行到列,显示在同一行上

时间:2016-09-10 00:34:00

标签: python pandas dataframe

我正在尝试移动我的一些行并将它们设为列,但保持数据帧的大部分相同。

生成的数据帧:

ID  Thing      Level1 Level2  Time OAttribute IsTrue Score Value
1   bicycle    value  value  9:30  whatever    yes   1     type1
1   bicycle    value  value  9:30  whatever    yes   2     type2
2   bicycle    value  value  2:30  whatever    no               
4   non-bic    value  value  3:30  whatever    no    4     type3
1   bicycle    value  value  9:30  whatever    yes   3     type3

我想要这样的事情:

ID  Thing  Level1 Level2  Time    OAttribute   IsTrue  Type1  Type2 Type3
1   bicycle    value  value  9:30  whatever     yes      1      2     3
2   bicycle    value  value  2:30  whatever     yes               
4   non-bic    value  value  3:30  whatever     no                    4

我试过了

df_ = df[['Rating', 'Value']].dropna().set_index('Value', append=True).Rating.unstack()

df.drop('Value', 1).merge(df_, right_index=True, left_index=True, how='left').fillna('')

2 个答案:

答案 0 :(得分:1)

一种方法是创建一个中间数据帧,然后使用外部合并。

In [102]: df
Out[102]: 
   ID    Thing Level1 Level2  Time OAttribute IsTrue  Score  Value
0   1  bicycle  value  value  9:30   whatever    yes    1.0  type1
1   1  bicycle  value  value  9:30   whatever    yes    2.0  type2
2   2  bicycle  value  value  2:30   whatever     no    NaN    NaN
3   4  non-bic  value  value  3:30   whatever     no    4.0  type3
4   1  bicycle  value  value  9:30   whatever    yes    3.0  type3

In [103]: dg = pd.DataFrame(columns=pd.np.append(df['Value'].dropna().unique(), ['ID']))

In [104]: for i in range(len(df)):
     ...:     key = df.loc[i]['Value']
     ...:     value = df.loc[i]['Score']
     ...:     ID = df.loc[i]['ID']
     ...:     if key is not pd.np.nan:
     ...:         dg.loc[i, key] = value
     ...:         dg.loc[i, 'ID'] = ID
     ...:                 

In [105]: dg
Out[105]: 
  type1 type2 type3 ID
0     1   NaN   NaN  1
1   NaN     2   NaN  1
3   NaN   NaN     4  4
4   NaN   NaN     3  1

In [106]: dg.groupby('ID').max().reset_index()

In [107]: dg
Out[107]: 
   ID  type1  type2  type3
0   1      1      2      3
1   4    NaN    NaN      4

In [108]: df[df.columns.difference(['Score', 'Value'])].drop_duplicates().merge(dg, how='outer').fillna('')
Out[108]: 
   ID IsTrue Level1 Level2 OAttribute    Thing  Time type1 type2 type3
0   1    yes  value  value   whatever  bicycle  9:30     1     2     3
1   2     no  value  value   whatever  bicycle  2:30                  
2   4     no  value  value   whatever  non-bic  3:30                 4

计算中间数据框的另一种方法是避免使用for循环并使用unstack()

In [150]: df
Out[150]: 
   ID    Thing Level1 Level2  Time OAttribute IsTrue  Score  Value
0   1  bicycle  value  value  9:30   whatever    yes    1.0  type1
1   1  bicycle  value  value  9:30   whatever    yes    2.0  type2
2   2  bicycle  value  value  2:30   whatever     no    NaN    NaN
3   4  non-bic  value  value  3:30   whatever     no    4.0  type3
4   1  bicycle  value  value  9:30   whatever    yes    3.0  type3

In [151]: dg = df[['Score', 'Value']].dropna().set_index('Value', append=True).Score.unstack().join(df['ID']).groupby('ID').max().reset_index()

In [152]: df[df.columns.difference(['Score', 'Value'])].drop_duplicates().merge(dg, how='outer').fillna('')
Out[152]: 
   ID IsTrue Level1 Level2 OAttribute    Thing  Time type1 type2 type3
0   1    yes  value  value   whatever  bicycle  9:30     1     2     3
1   2     no  value  value   whatever  bicycle  2:30                  
2   4     no  value  value   whatever  non-bic  3:30                 4

答案 1 :(得分:0)

无法同时告诉您同时尝试使用“得分”和“值”列进行操作。

但如果您正在寻求改变您的价值"专栏,您正在寻找类似于"价值"的热门编码之类的内容。 column和pandas有一个非常方便的功能。您所要做的就是:

pd.get_dummies(df['Value'])

这将为您提供一个包含3个新列的新数据框,即[type1,type2,type3]填充一堆1和0。

之后,您只需使用.join命令将其连接回原始df即可。然后,您可以继续删除您不需要的列。