将数据框与具有索引重复项并排除一列的系列相乘
Multiply dataframe with series having index duplicates and excluding one column
我的数据框的简化版本如下所示:
df_crop = pd.DataFrame({
'Name' : ['Crop1', 'Crop1', 'Crop1', 'Crop1', 'Crop2', 'Crop2', 'Crop2', 'Crop2'],
'Type' : ['Area', 'Diesel', 'Fert', 'Pest', 'Area', 'Diesel', 'Fert', 'Pest'],
'GHG': [14.9, 0.0007, 0.145, 0.1611, 2.537, 0.011, 0.1825, 0.115],
'Acid': [0.0125, 0.0005, 0.0029, 0.0044, 0.013, 0.00014, 0.0033, 0.0055],
'Terra Eutro': [0.053, 0.0002, 0.0077, 0.0001, 0.0547, 0.00019, 0.0058, 0.0002]
})
我现在需要使用产量对数据框中的所有值进行归一化,产量因作物不同而不同,但类型不同:
s_yield = pd.Series([0.388, 0.4129],
index=['Crop1', 'Crop2'])
我需要保留 'Type' 中的信息。如果我尝试使用 .mul()
,由于索引重复,我会收到错误消息:ValueError: cannot reindex from a duplicate axis
.
我唯一的其他想法是使用 .loc()
,但我有很多列(16 个值要归一化)并且没有想到有效的方法。有什么建议吗?
编辑:
以下 table 可能有助于展示我试图实现的目标:
从 pandas 0.24.0 开始,只要系列命名为:
就可以直接将系列合并到 DataFrame 中
df_merged = df_crop.merge(s_yield.rename('yield'), left_on = 'Name', right_index = True)
然后根据需要乘以列。
获取数值数据并使用级数相乘
numeric_df = df_crop.select_dtypes('number')
df_crop[numeric_df.columns] = numeric_df.mul(df_crop.Name.map(s_yield), axis=0)
输出
Name Type GHG Acid Terra Eutro
0 Crop1 Area 5.781200 0.004850 0.020564
1 Crop1 Diesel 0.000272 0.000194 0.000078
2 Crop1 Fert 0.056260 0.001125 0.002988
3 Crop1 Pest 0.062507 0.001707 0.000039
4 Crop2 Area 1.047527 0.005368 0.022586
5 Crop2 Diesel 0.004542 0.000058 0.000078
6 Crop2 Fert 0.075354 0.001363 0.002395
7 Crop2 Pest 0.047483 0.002271 0.000083
您可以使用 s_yield.map
将系列扩展到数据帧的长度,并且您可以使用 df.select_dtypes
查找特定数据类型的所有列和多个列:
cols = df_crop.select_dtypes('number').columns
df_crop[cols] = df_crop[cols].mul(df_crop['Name'].map(s_yield), axis=0)
输出:
>>> df_crop
Name Type GHG Acid Terra Eutro
0 Crop1 Area 5.781200 0.004850 0.020564
1 Crop1 Diesel 0.000272 0.000194 0.000078
2 Crop1 Fert 0.056260 0.001125 0.002988
3 Crop1 Pest 0.062507 0.001707 0.000039
4 Crop2 Area 1.047527 0.005368 0.022586
5 Crop2 Diesel 0.004542 0.000058 0.000078
6 Crop2 Fert 0.075354 0.001363 0.002395
7 Crop2 Pest 0.047483 0.002271 0.000083
设置 df_crop 的索引,并与系列相乘,在相关级别对齐:
temp = df_crop.set_index(['Name', 'Type'])
temp.mul(s_yield, level='Name', axis = 0).reset_index()
Name Type GHG Acid Terra Eutro
0 Crop1 Area 5.781200 0.004850 0.020564
1 Crop1 Diesel 0.000272 0.000194 0.000078
2 Crop1 Fert 0.056260 0.001125 0.002988
3 Crop1 Pest 0.062507 0.001707 0.000039
4 Crop2 Area 1.047527 0.005368 0.022586
5 Crop2 Diesel 0.004542 0.000058 0.000078
6 Crop2 Fert 0.075354 0.001363 0.002395
7 Crop2 Pest 0.047483 0.002271 0.000083
我的数据框的简化版本如下所示:
df_crop = pd.DataFrame({
'Name' : ['Crop1', 'Crop1', 'Crop1', 'Crop1', 'Crop2', 'Crop2', 'Crop2', 'Crop2'],
'Type' : ['Area', 'Diesel', 'Fert', 'Pest', 'Area', 'Diesel', 'Fert', 'Pest'],
'GHG': [14.9, 0.0007, 0.145, 0.1611, 2.537, 0.011, 0.1825, 0.115],
'Acid': [0.0125, 0.0005, 0.0029, 0.0044, 0.013, 0.00014, 0.0033, 0.0055],
'Terra Eutro': [0.053, 0.0002, 0.0077, 0.0001, 0.0547, 0.00019, 0.0058, 0.0002]
})
我现在需要使用产量对数据框中的所有值进行归一化,产量因作物不同而不同,但类型不同:
s_yield = pd.Series([0.388, 0.4129],
index=['Crop1', 'Crop2'])
我需要保留 'Type' 中的信息。如果我尝试使用 .mul()
,由于索引重复,我会收到错误消息:ValueError: cannot reindex from a duplicate axis
.
我唯一的其他想法是使用 .loc()
,但我有很多列(16 个值要归一化)并且没有想到有效的方法。有什么建议吗?
编辑:
以下 table 可能有助于展示我试图实现的目标:
从 pandas 0.24.0 开始,只要系列命名为:
就可以直接将系列合并到 DataFrame 中df_merged = df_crop.merge(s_yield.rename('yield'), left_on = 'Name', right_index = True)
然后根据需要乘以列。
获取数值数据并使用级数相乘
numeric_df = df_crop.select_dtypes('number')
df_crop[numeric_df.columns] = numeric_df.mul(df_crop.Name.map(s_yield), axis=0)
输出
Name Type GHG Acid Terra Eutro
0 Crop1 Area 5.781200 0.004850 0.020564
1 Crop1 Diesel 0.000272 0.000194 0.000078
2 Crop1 Fert 0.056260 0.001125 0.002988
3 Crop1 Pest 0.062507 0.001707 0.000039
4 Crop2 Area 1.047527 0.005368 0.022586
5 Crop2 Diesel 0.004542 0.000058 0.000078
6 Crop2 Fert 0.075354 0.001363 0.002395
7 Crop2 Pest 0.047483 0.002271 0.000083
您可以使用 s_yield.map
将系列扩展到数据帧的长度,并且您可以使用 df.select_dtypes
查找特定数据类型的所有列和多个列:
cols = df_crop.select_dtypes('number').columns
df_crop[cols] = df_crop[cols].mul(df_crop['Name'].map(s_yield), axis=0)
输出:
>>> df_crop
Name Type GHG Acid Terra Eutro
0 Crop1 Area 5.781200 0.004850 0.020564
1 Crop1 Diesel 0.000272 0.000194 0.000078
2 Crop1 Fert 0.056260 0.001125 0.002988
3 Crop1 Pest 0.062507 0.001707 0.000039
4 Crop2 Area 1.047527 0.005368 0.022586
5 Crop2 Diesel 0.004542 0.000058 0.000078
6 Crop2 Fert 0.075354 0.001363 0.002395
7 Crop2 Pest 0.047483 0.002271 0.000083
设置 df_crop 的索引,并与系列相乘,在相关级别对齐:
temp = df_crop.set_index(['Name', 'Type'])
temp.mul(s_yield, level='Name', axis = 0).reset_index()
Name Type GHG Acid Terra Eutro
0 Crop1 Area 5.781200 0.004850 0.020564
1 Crop1 Diesel 0.000272 0.000194 0.000078
2 Crop1 Fert 0.056260 0.001125 0.002988
3 Crop1 Pest 0.062507 0.001707 0.000039
4 Crop2 Area 1.047527 0.005368 0.022586
5 Crop2 Diesel 0.004542 0.000058 0.000078
6 Crop2 Fert 0.075354 0.001363 0.002395
7 Crop2 Pest 0.047483 0.002271 0.000083