【问题标题】:calculate values between two pandas dataframe based on a column value根据列值计算两个熊猫数据框之间的值
【发布时间】:2015-08-09 22:46:49
【问题描述】:

已编辑:让我复制整个数据集

df 是商店销售/库存数据

  branch   daqu store     store_name       style  color  size  stocked    sold  in_stock  balance
0  huadong  wenning  C301  EE #��#��##��  EEBW52301M     39   160        7    4         3       -5
1  huadong  wenning  C301  EE #��#��##��  EEBW52301M     39   165        1    0         1        1
2  huadong  wenning  C301  EE #��#��##��  EEBW52301M     39   170        6    3         3       -3

dh 是交易(将 'amount' 从 store 'from' 移动到 'to')

    branch      daqu  from    to       style  color  size  amount  box_sum
8   huadong  shanghai  C306  C30C  EEOM52301M     59   160       1      162
18  huadong  shanghai  C306  C30C  EEOM52301M     39   160       1      162
25  huadong  shanghai  C306  C30C  EETJ52301M     52   160       9      162
26  huadong  shanghai  C306  C30C  EETJ52301M     52   155       1      162
32  huadong  shanghai  C306  C30C  EEOW52352M     19   160       2      162

我想要的是交易后的商店库存数据,它看起来与 df 的格式完全相同,但根据 dh 中的数字,只有“in_stock”数字会从原始 df 发生变化。

以下是我尝试过的:

df['full_code'] = df['store']+df['style']+df['color'].astype(str)+df['size'].astype(str)    
dh['from_code'] = dh['from']+dh['style']+dh['color'].astype(str)+dh['size'].astype(str)
dh['to_code'] = dh['to']+dh['style']+dh['color'].astype(str)+dh['size'].astype(str)


# subtract from 'from' store
dh_from = pd.DataFrame(dh.groupby('from_code')['amount'].sum())

for code, stock in dh_from.iterrows() :
    df.loc[df['full_code'] == code, 'in_stock'] = df.loc[df['full_code'] == code, 'in_stock'] - stock

# add to 'to' store    
dh_to = pd.DataFrame(dh.groupby('to_code')['amount'].sum())

for code, stock in dh_to.iterrows() :
    df.loc[df['full_code'] == code, 'in_stock'] = df.loc[df['full_code'] == code, 'in_stock'] + stock

df.to_csv('d:/after_dh.csv')

但是当我打开 csv 文件时,那些发生交易的 'in_stock' 值都是空白的。 我认为df.loc[df['full_code'] == code, 'in_stock'] = df.loc[df['full_code'] == code, 'in_stock'] + stock 这有一些问题。更新值的正确方法是什么?


原文:我有两个 pandas 数据框:df1 用于库存,df2 用于交易

df1 看起来像这样:

   full_code in_stock
1  AAA       200
2  BBB       150
3  CCC       150

df2 看起来像这样:

   from   to   full_code  amount
1  XX     XY   AAA        30
2  XX     XZ   AAA        35
3  ZY     OI   BBB        50
4  AQ     TR   AAA        15

我想要的是所有交易完成后的库存。 在这种情况下,

   full_code in_stock
1  AAA       120
2  BBB       100
3  CCC       150

请注意,full_code 在 df1 中是唯一的,但在 df2 中不是唯一的。 有没有什么熊猫方法可以做到这一点?我弄乱了原始数据框和数据框的视图,并通过将它们转换为 numpy 数组并找到匹配的 full_codes 来解决它。但是生成的代码也是一团糟,想知道是否有更简单的方法可以不把所有东西都变成一个 numpy 数组。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    我要做的是将df1 中的索引设置为“full_code”列,然后调用sub 减去另一个df。

    我们传递的值是对 'full_code' 进行分组并在 'amount' 列上调用 sum 的结果。

    sub 的附加参数是fill_values,这是因为 rhs 上不存在产品“CCC”,因此我们希望保留此值,否则将变为 NaN

    In [25]:
    
    total = df1.set_index('full_code')['in_stock'].sub(df2.groupby('full_code')['amount'].sum(), fill_value=0)
    total.reset_index()
    ​
    Out[25]:
      full_code  in_stock
    0       AAA       120
    1       BBB       100
    2       CCC       150
    

    【讨论】:

    • 谢谢,还有一个问题:实际上在 df1 我有更多的专栏。此代码丢弃了除 full_code 和 in_stock 之外的所有列,还有其他方法可以使它们保持活力吗?
    • 你可以将这个结果分配/合并回你的df,所以使用上面的代码你可以做df1.merge(total.reset_index(), on='full_code')我认为应该可以工作
    • 我试过 df1 = df.set_index('full_code')['in_stock'].sub(dh_final.groupby('full_code')['amount'].sum(), fill_value=0) df1.reset_index() df1.columns = ['full_code', 'in_stock'] print type(df1) print df1.head(5) 但它给了 <class 'pandas.core.series.Series'> full_code C301EEBW52301M39160 3 C301EEBW52301M39165 1 C301EEBW52301M39170 3 C301EEBW52301M51160 1 C301EEBW52301M51165 1 Name: in_stock, dtype: float64 我想知道为什么 df.sub() 返回一个系列而不是一个数据框...
    • 如果您的起始 df 只有 2 列,然后您将其中 1 列设置为索引,这可能会将其转换为 Series 是我的猜测
    最近更新 更多