【问题标题】:Multiply dataframe with series having index duplicates and excluding one column将数据框与具有索引重复且不包括一列的系列相乘
【发布时间】:2021-12-28 23:34:46
【问题描述】:

我的数据框的缩短版本如下所示:

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'])

我需要保留“类型”中的信息。如果我尝试使用.mul(),我会因为重复的索引而收到错误:ValueError: cannot reindex from a duplicate axis

我唯一的另一个想法是使用.loc(),但我有很多列(16 列有要规范化的值)并且没有想到任何有效的。有什么建议吗?

编辑: 下表可能有助于显示我试图实现的目标:

【问题讨论】:

  • 请发布您预期的输出数据框

标签: python pandas dataframe series


【解决方案1】:

获取数值数据并使用系列相乘

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

【讨论】:

  • 哈哈,我们的答案非常相似! ;) +1
  • 伟大的思想都一样:P
  • 它就像一个魅力!非常感谢!
【解决方案2】:

为 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

【讨论】:

  • 虽然是一个很好的答案,但如果有更多的字符串列,它可能会丢失列。 @switchback
  • @Vishnudev 是的,我的答案仅限于共享的示例数据。
  • 而且我确实没有任何其他字符串列,所以在我的情况下这是完美的。但我同意您的解决方案更灵活。
【解决方案3】:

从 pandas 0.24.0 开始,您可以直接将系列合并到数据框,只要系列被命名:

df_merged = df_crop.merge(s_yield.rename('yield'), left_on = 'Name', right_index = True)

然后根据需要将列相乘。

【讨论】:

  • 如果我正确理解了您的建议,那么我就可以独立地将每一列相乘,对吗?
  • 您可以同时将多列乘以一列,例如df_merged[['GHG', 'Acid', 'Terra Eutro']].multiply(df_merged['yield'], axis = 0)
【解决方案4】:

您可以使用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

【讨论】:

    猜你喜欢
    • 2012-10-21
    • 2015-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-19
    • 1970-01-01
    相关资源
    最近更新 更多