【问题标题】:Pandas divide two dataframe with different sizes熊猫划分两个不同大小的数据框
【发布时间】:2020-05-05 17:47:24
【问题描述】:

我有一个数据框 df1:

col1 col2 Val1 Val2
A    g    4    6
A    d    3    8
B    h    5    10
B    p    7    14

我有另一个数据框 df2:

col1 Val1 Val2
A    2    3
B    1    4

我想根据 col1、val1 和 val2 将 df1 除以 df2,以便 df2 中的行 AAdf1 中的两行分开。

df1.div(df2)的最终输出如下:

col1 col2 Val1 Val2
A    g    2    2
A    d    1.5  2
B    h    5    2.5
B    p    7    3.5

【问题讨论】:

  • 对于A d 3 8 的行,预期的输出几乎肯定是不正确的。 8 除以 3 不是 2,而是 2.666666667

标签: python pandas python-3.5


【解决方案1】:

我认为你的例子有一个小错误。对于 col Val2,第 2 行 - 8/3 应该是 2.67。所以最终输出df1.div(df2) 应该是:

  col1 col2  Val1      Val2
0    A    g   2.0  2.000000
1    A    d   1.5  2.666667
2    B    h   5.0  2.500000
3    B    p   7.0  3.500000

无论如何,这是一个可能的解决方案:

  1. 构造 2 个 dfs
import pandas as pd

df1 = pd.DataFrame(data={'col1':['A','A','B','B'], 'col2': ['g','d','h','p'], 'Val1': [4,3,5,7], 'Val2': [6,8,10,14]}, columns=['col1','col2','Val1','Val2'])

df2 = pd.DataFrame(data={'col1':['A','B'], 'Val1': [2,1], 'Val2': [3,4]}, columns=['col1','Val1','Val2'])

print (df1)
print (df2)

输出:

>>>
col1 col2  Val1  Val2
0    A    g     4     6
1    A    d     3     8
2    B    h     5    10
3    B    p     7    14

  col1  Val1  Val2
0    A     2     3
1    B     1     4

现在我们可以在 col:col1 上执行 INNER JOINdf1df2。如果您不熟悉 SQL 连接,请查看:sql-join。我们可以使用 merge() method 加入 pandas

## join df1, df2

merged_df = pd.merge(left=df1, right=df2, how='inner', on='col1')

print (merged_df)

输出:

>>>
col1 col2  Val1_x  Val2_x  Val1_y  Val2_y
0    A    g       4       6       2       3
1    A    d       3       8       2       3
2    B    h       5      10       1       4
3    B    p       7      14       1       4

现在我们已经得到了df1df2的对应列,我们可以简单地计算除法并删除冗余列:

# Val1 = Val1_x/Val1_y, Val2 = Val2_x/Val2_y

merged_df['Val1'] = merged_df['Val1_x']/merged_df['Val1_y']
merged_df['Val2'] = merged_df['Val2_x']/merged_df['Val2_y']

# delete the cols: Val1_x,Val1_y,Val2_x,Val2_y

merged_df.drop(columns=['Val1_x', 'Val1_y', 'Val2_x', 'Val2_y'], inplace=True)

print (merged_df)

最终输出:

  col1 col2  Val1      Val2
0    A    g   2.0  2.000000
1    A    d   1.5  2.666667
2    B    h   5.0  2.500000
3    B    p   7.0  3.500000

我希望这能解决你的问题:)

【讨论】:

    【解决方案2】:

    您可以使用pandas.merge() function 执行database-like join between dataframes,然后使用结果除列值:

    # merge against col1 so we get a merged index
    merged = pd.merge(df1[["col1"]], df2)
    df1[["Val1", "Val2"]] = df1[["Val1", "Val2"]].div(merged[["Val1", "Val2"]])
    

    这会产生:

      col1 col2  Val1      Val2
    0    A    g   2.0  2.000000
    1    A    d   1.5  2.666667
    2    B    h   5.0  2.500000
    3    B    p   7.0  3.500000
    

    【讨论】:

      【解决方案3】:

      col1col2 转换为MultiIndex,同时将col1 在第二个DataFrame 转换为索引,然后使用DataFrame.div

      df = df1.set_index(['col1', 'col2']).div(df2.set_index('col1')).reset_index()
      #alternative with specify level of index
      #df = df1.set_index(['col1', 'col2']).div(df2.set_index('col1'), level=0).reset_index()
      print (df)
        col1 col2  Val1      Val2
      0    A    g   2.0  2.000000
      1    A    d   1.5  2.666667
      2    B    h   5.0  2.500000
      3    B    p   7.0  3.500000
      

      【讨论】:

        猜你喜欢
        • 2021-01-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多