Pandas DataFrame - 根据df

时间:2016-07-19 12:37:23

标签: python pandas dataframe

对未明确标题的道歉。到目前为止,我一直在不知不觉中试图想出一种基于某些列的内容向pandas数据帧添加新“行”的方法。我希望通过一个例子说清楚。这些数据是模拟数据,有望在绘制更大的图片时足够。

因此,假设一位汽车经销商拥有以下7位客户。在数据框中,您可以看到他们的客户ID,他们的性别(因为为什么不是),以及他们目前居住的国家。此外,您可以看到他们是否购买了四个汽车品牌中的任何一个(以及哪种类型的汽车)或不(NA)(数据帧中的所有值都是字符串btw)。例如,客户4是来自俄罗斯的女性,她从经销商处购买了一辆保时捷911。

        Cust-id Sex Country Audi Ferrari Porsche Jaguar
    0   Cu1      F    FR     R8    FF      NA     NA
    1   Cu2      M    US     NA    NA      NA     XF
    2   Cu3      M    UK     RS7   NA      NA     NA
    3   Cu4      F    RU     NA    NA      911    NA
    4   Cu5      M    US     NA    NA      918    Ford
    5   Cu6      F    US     S6    NA      NA     F-type
    6   Cu7      M    UK     A8    NA      MacanS XE

我希望能够做的是为客户购买多辆汽车的情况创建新行,每行只指定一辆汽车,其他汽车品牌列都说“NA”那个特定的行。对于上面的示例,这将导致以下数据帧。

            Cust-id Sex Country Audi Ferrari Porsche Jaguar
    0         Cu1    F    FR     R8    NA      NA     NA
    1         Cu1    F    FR     NA    FF      NA     NA
    2         Cu2    M    US     NA    NA      NA     XF
    3         Cu3    M    UK     RS7   NA      NA     NA
    4         Cu4    F    RU     NA    NA      911    NA
    5         Cu5    M    US     NA    NA      918    NA
    6         Cu5    M    US     NA    NA      NA     Ford
    7         Cu6    F    US     S6    NA      NA     F-type
    8         Cu7    M    UK     A8    NA      NA     NA
    9         Cu7    M    UK     NA    NA      MacanS NA
    10        Cu7    M    UK     NA    NA      NA     XE

这意味着指定了三辆车的原始行将导致三个新行,每行仅指定一辆车(原始行已消失)。 Cust-id,Sex和Country值不会更改。第一次使用网站自己提问,所以希望格式化不是太糟糕。感谢任何帮助/指导。 python pandas dataframe

2 个答案:

答案 0 :(得分:1)

我接近这个的方法如下:

  1. 迭代每个car列并仅保留具有非空值的记录

    df_dict = {}
    
    for car in ['Audi', 'Ferrari', 'Porsche' ,'Jaguar']:  
    
        non_nulls = df[ df.apply(lambda x: not pd.isnull(x[car] ), axis=1)]
    
        df_dict[car] = non_nulls[[Cust-id,Sex,Country, car]]
    
  2. 将数据框与pd.concat连接起来,这将在正确的位置创建空值

    final_df = pd.concat( df_dict.values() )
    
  3. 这些方面应该有所作为。虽然没有测试我的代码,所以请自己判断!

答案 1 :(得分:0)

import pandas as pd

df = pd.DataFrame({'Audi': ['R8', 'NA', 'RS7', 'NA', 'NA', 'S6', 'A8'],
 'Country': ['FR', 'US', 'UK', 'RU', 'US', 'US', 'UK'],
 'Cust-id': ['Cu1', 'Cu2', 'Cu3', 'Cu4', 'Cu5', 'Cu6', 'Cu7'],
 'Ferrari': ['FF', 'NA', 'NA', 'NA', 'NA', 'NA', 'NA'],
 'Jaguar': ['NA', 'XF', 'NA', 'NA', 'Ford', 'F-type', 'XE'],
 'Porsche': ['NA', 'NA', 'NA', '911', '918', 'NA', 'MacanS'],
 'Sex': ['F', 'M', 'M', 'F', 'M', 'F', 'M']})

result = pd.melt(df, id_vars=['Cust-id', 'Sex', 'Country'])
mask = result['value'] != 'NA'
result = result.loc[mask]
result['index'] = result.index
result = pd.concat([result[['Cust-id', 'Sex', 'Country']], 
           result.pivot(index='index', columns='variable', values='value')], axis=1)

print(result)

产量

   Cust-id Sex Country  Audi Ferrari  Jaguar Porsche
0      Cu1   F      FR    R8    None    None    None
2      Cu3   M      UK   RS7    None    None    None
5      Cu6   F      US    S6    None    None    None
6      Cu7   M      UK    A8    None    None    None
7      Cu1   F      FR  None      FF    None    None
15     Cu2   M      US  None    None      XF    None
18     Cu5   M      US  None    None    Ford    None
19     Cu6   F      US  None    None  F-type    None
20     Cu7   M      UK  None    None      XE    None
24     Cu4   F      RU  None    None    None     911
25     Cu5   M      US  None    None    None     918
27     Cu7   M      UK  None    None    None  MacanS

您可以使用melt将汽车列合并为一列:

In [232]: result = pd.melt(df, id_vars=['Cust-id', 'Sex', 'Country']); result.head()
Out[232]: 
  Cust-id Sex Country variable value
0     Cu1   F      FR     Audi    R8
1     Cu2   M      US     Audi    NA
2     Cu3   M      UK     Audi   RS7
3     Cu4   F      RU     Audi    NA
4     Cu5   M      US     Audi    NA
...

删除包含'NA'字符串值的行:

mask = result['value'] != 'NA'
result = result.loc[mask]

然后使用pivot重塑结果。 pivotroughly the inverse of pd.melt - 它会将一列中的值(例如'variable')分散到多列中,从而取消合并汽车列。

result['index'] = result.index
result = pd.concat([result[['Cust-id', 'Sex', 'Country']], 
           result.pivot(index='index', columns='variable', values='value')], axis=1)

result['index'] = result.index用于确保pivot按原样保留行。