对未明确标题的道歉。到目前为止,我一直在不知不觉中试图想出一种基于某些列的内容向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
答案 0 :(得分: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]]
将数据框与pd.concat
连接起来,这将在正确的位置创建空值
final_df = pd.concat( df_dict.values() )
这些方面应该有所作为。虽然没有测试我的代码,所以请自己判断!
答案 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
重塑结果。 pivot
为roughly 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按原样保留行。