2016-12-12 89 views
0

我刚开始使用熊猫,并且有一个数据框包含具有相同索引的多行,表示变量具有某些特征,例如,熊猫:合并具有相同索引的行,同时创建一个新列

ItemID  Property Numerical_value 
A1   'Red'  10  
A1   'Fruit'  0 
B1   'Red'  25 
C1   'Liquid' 0 

对我的数据持有的假设是; 只有属性为“红色”的行才有数字值。并且 如果一个物品具有属性'水果',它也具有属性红色。

我面临的问题是将这个日期框架转换为每个itemID的单一编码方案,同时也保存数值(如果存在的话)。

ItemID  Red&Fruit Just_red Other Numerical_value 
A1   1   0   0  10   
B1   0   1   0  25 
C1   0   0   1  0 

目前,我写了下面的代码;

def read_report: 
    fp = 'file_path' 
    df = (pd.read_csv(fp)) 
    group = df.groupby('ItemID')['Property','Numerical_value'].apply(test_function) 

def test_function(df): 
    if 'Fruit' in df.values: 
     num_val = df[df['Property'] == 'Red']['Numerical_value'].values[0] 
     return pd.Series({'Red&Fruit': '1', 'Num_val': num_val}) 
    elif 'Red' in df.values: 
     num_val= df[df['Property'] == 'Red']['Num_val'].values[0] 
     return pd.Series({'Just_red': '1', 'Num_val': num_val}) 
    else: 
     return pd.Series({'Other': '1', 'Num_val': 0}) 

这似乎不是最佳的,尤其是得到的数值为每概括行的感觉,而哈克的方式。

有没有更好的方法来达到同样的效果?

+1

你的问题对我来说并不完全清楚:在第1组中,你有一个项目'红色'和一个项目'水果',根据你所说的'红色和水果'。这两个不同的对象?或者任何时候有'水果',也会有'红色'? – FLab

+0

你最后的陈述是正确的,它是同一个对象。如果我们遇到属性'水果',我们相信它也有属性'红'。 –

回答

3

我会建议由集团获得的一组属性:

df.groupby('ItemID')['Property'].apply(set) 
Out[15]: 
ItemID 
A1 {'Red', 'Fruit'} 
B1    {'Red'} 
C1   {'Liquid'} 

然后,您可以使用get_dummies

df.groupby('ItemID')['Property'].apply(set).str.get_dummies() 
Out[17]: 
     {"'Liquid'"} {"'Red'", "'Fruit'"} {"'Red'"} 
ItemID            
A1     0      1   0 
B1     0      0   1 
C1     1      0   0 

在你的榜样,你只需要重新命名列。但是,您可能需要在groupby操作后replace的值。

最后,合并与数值:

pd.concat([df.groupby('ItemID')['Property'].apply(set).str.get_dummies(), 
      df.groupby('ItemID')['Numerical_value'].first()], axis=1) 
Out[21]: 
     {"'Liquid'"} {"'Red'", "'Fruit'"} {"'Red'"} Numerical_value 
ItemID                 
A1     0      1   0    10 
B1     0      0   1    25 
C1     1      0   0    0 

在这里,我采取的第一个数值,因为在你的榜样。

相关问题