【问题标题】:Pandas: 1 dataframe comparing rows to create new columnPandas:1个数据框比较行以创建新列
【发布时间】:2019-02-23 11:16:05
【问题描述】:

我有一个问题,我似乎无法理解。

df1如下:

Group     item     Quarter    price    quantity

1         A        2017Q3     0.10     1000 
1         A        2017Q4     0.11     1000 
1         A        2018Q1     0.11     1000
1         A        2018Q2     0.12     1000 
1         A        2018Q3     0.11     1000

所需的结果是一个新的数据框,称为 df2 并带有一个附加列。

Group     item     Quarter    price    quantity    savings/lost

1         A        2017Q3     0.10     1000         0.00   
1         A        2017Q4     0.11     1000         0.00
1         A        2018Q1     0.11     1000         0.00
1         A        2018Q2     0.12     1000         0.00
1         A        2018Q3     0.11     1000         10.00
1         A        2018Q4     0.13     1000         -20.00

基本上,我想走下每一行,查看季度并找到去年的类似季度并进行计算(本季度价格 - 上季度价格 * 数量)。如果没有上一季度的数据,就在最后一列。

为了完成图片,那里有更多的组和项目,甚至更多的季度,如 2016Q1、2017Q1、2018Q1,尽管我只需要比较前一年。季度是字符串格式。

【问题讨论】:

  • 查看pandas.Period 了解更多信息。在YearWithQuarter 也有与之相关的讨论。我希望这会对你有所帮助。
  • 似乎遍历行是唯一的解决方案,对吧?抱歉,由于我对 pandas 的使用非常简单,所以我无法理解。就像取一整列并乘以另一列来创建一个新列。

标签: pandas


【解决方案1】:

使用pandas.DataFrame.shift

下面的代码假定您的列Quarter 已排序并且没有丢失季度。你可以试试下面的代码:

# Input dataframe
  Group item Quarter  price  quantity
0     1    A  2017Q3   0.10      1000
1     1    A  2017Q4   0.11      1000
2     1    A  2018Q1   0.11      1000
3     1    A  2018Q2   0.12      1000
4     1    A  2018Q3   0.11      1000
5     1    A  2018Q4   0.13      1000

# Code to generate your new column 'savings/lost'
df['savings/lost'] =  df['price'] * df['quantity'] - df['price'].shift(4) * df['quantity'].shift(4)

# Output dataframe
  Group item Quarter  price  quantity  savings/lost
0     1    A  2017Q3   0.10      1000           NaN
1     1    A  2017Q4   0.11      1000           NaN
2     1    A  2018Q1   0.11      1000           NaN
3     1    A  2018Q2   0.12      1000           NaN
4     1    A  2018Q3   0.11      1000          10.0
5     1    A  2018Q4   0.13      1000          20.0

更新

我更新了我的代码来处理两件事,首先对Quarter 进行排序,然后处理缺少的Quarter 场景。对于基于列的分组,您可以参考pandas.DataFrame.groupby 和本网站已回答的许多pd.groupby 相关问题。

#Input dataframe
  Group item Quarter  price  quantity
0     1    A  2014Q3   0.10       100
1     1    A  2017Q2   0.16       800
2     1    A  2017Q3   0.17       700
3     1    A  2015Q4   0.13       400
4     1    A  2016Q1   0.14       500
5     1    A  2014Q4   0.11       200
6     1    A  2015Q2   0.12       300
7     1    A  2016Q4   0.15       600
8     1    A  2018Q1   0.18       600
9     1    A  2018Q2   0.19       500

#Code to do the operations
df.index = pd.PeriodIndex(df.Quarter, freq='Q')
df.sort_index(inplace=True)
df2 = df.reset_index(drop=True)
df2['Profit'] = (df.price * df.quantity) - (df.reindex(df.index - 4).price * df.reindex(df.index - 4).quantity).values
df2['Profit'] = np.where(np.in1d(df.index - 4, df.index.values),
                        df2.Profit, ((df.price * df.quantity) - (df.price.shift(1) * df.quantity.shift(1))))
df2.Profit.fillna(0, inplace=True)

#Output dataframe
  Group item Quarter  price  quantity  Profit
0     1    A  2014Q3   0.10       100     0.0
1     1    A  2014Q4   0.11       200    12.0
2     1    A  2015Q2   0.12       300    14.0
3     1    A  2015Q4   0.13       400     0.0
4     1    A  2016Q1   0.14       500    18.0
5     1    A  2016Q4   0.15       600     0.0
6     1    A  2017Q2   0.16       800    38.0
7     1    A  2017Q3   0.17       700    -9.0
8     1    A  2018Q1   0.18       600   -11.0
9     1    A  2018Q2   0.19       500     0.0

【讨论】:

  • 谢谢。不幸的是,将缺少季度和年份。看起来我确实需要用 2 个循环遍历行...
  • 请使用具有所有条件的真实输入数据框和预期的输出数据框更新您的问题。看看MCVE
猜你喜欢
  • 1970-01-01
  • 2019-12-20
  • 1970-01-01
  • 2017-05-17
  • 1970-01-01
  • 2020-11-25
  • 1970-01-01
  • 2017-02-20
  • 1970-01-01
相关资源
最近更新 更多