【问题标题】:pandas taking average of certain rows while keeping others unchanged大熊猫取某些行的平均值,同时保持其他行不变
【发布时间】:2017-09-14 10:59:20
【问题描述】:

我有两个数据框:df1 和 df2。

df1包含每日数据,有4列:date、id、value1、value2;

df2 包含某个 id 发生某些事件的日期;它有两列:日期和 ID。

df2 是 df1 中日期和 id 列的子集

对于 df2 中的每一行,我想在 df1 中找到具有相同日期和 id 的行,并获取该 id 从 date-1 到 date+1 的行,取平均值并替换前三行.

例如,如果我有来自 df2 的 date = 3 和 id = A,我想在 (2, 3, 4) 和 df1 中找到 id = A 的行,取这些行的平均值并替换这三行加上结果一行。

df1:

index date id value1 value2
  0    1    A  0.1     0.2
  1    2    A  0.2     0.3
  2    3    A  0.3     0.4
  3    4    A  0.4     0.5
  4    5    A  0.5     0.6
  5    1    B  0.1     0.2
  6    2    B  0.2     0.3
  7    3    B  0.3     0.4
  8    4    B  0.4     0.5
  9    5    B  0.5     0.6

df2

index date id
  0     3    A
  1     3    B

想要的输出

index date id value1 value2
  0    1    A  0.1     0.2
  1    3    A  0.3     0.4
  2    5    A  0.5     0.6
  3    1    B  0.1     0.2
  4    3    B  0.3     0.4
  5    5    B  0.5     0.6

【问题讨论】:

  • 您自己在拼写解决方案:“我想在 (2, 3, 4) 中查找日期为 df1 中的 id = A 的行”......再加上其余的你的细节,你的尝试是什么样的?您已经分解了问题,现在如何将其转换为代码?考虑过滤和使用pandas.Series.isin...

标签: python pandas time-series


【解决方案1】:

注意事项:

  • 您似乎想要计算具有居中窗口的 3 个周期滚动平均值。
  • 然后仅对事件列表中的相关行进行切片 (df2)
  • 最后,用这些值更新第一个数据帧 (df1)

计划:

  • 使用pd.DataFrame.rolling 和参数window=3center=True
  • 因为我稍后需要更新,所以我打算将列 ['date', 'id'] 放入索引中。
  • 由于 df2 除了充当索引之外没有做任何其他事情,我将明确地将其设为索引
  • 最后,我将使用locreset_index 更新数据框

d1 = df1.set_index(['date', 'id'])
idx = pd.MultiIndex.from_arrays(df2.values.T)

d1.loc[idx] = d1.groupby(level='id', group_keys=False).rolling(3, center=True).mean()

d1.reset_index()

   date id  value1  value2
0     1  A     0.1     0.2
1     2  A     0.8     0.3
2     3  A     0.5     0.5
3     4  A     0.4     0.8
4     5  A     0.5     0.6
5     1  B     0.1     0.2
6     2  B     0.2     0.3
7     3  B     0.3     0.4
8     4  B     0.4     0.5
9     5  B     0.5     0.6

设置

# Note that changed the values of
# the 2nd row of value1 and 
# the 4th row of value2 in order to
# highlight that this works
df1 = pd.DataFrame({
        'date': [1, 2, 3, 4, 5, 1, 2, 3, 4, 5],
        'id': ['A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B'],
        'value1': [0.1, 0.8, 0.3, 0.4, 0.5, 0.1, 0.2, 0.3, 0.4, 0.5],
        'value2': [0.2, 0.3, 0.4, 0.8, 0.6, 0.2, 0.3, 0.4, 0.5, 0.6]
    })

df2 = pd.DataFrame({'date': [3, 3], 'id': ['A', 'B']})

【讨论】:

    【解决方案2】:
    pd.concat([df1[(df1['id'] == row['id']) & df1['date'].isin([row['date'], row['date'] - 1, row['date'] + 1])] for _, row in df2.iterrows()])
    

    这将导致:

           date id  value1  value2
    index                         
    1         2  A     0.2     0.3
    2         3  A     0.3     0.4
    3         4  A     0.4     0.5
    6         2  B     0.2     0.3
    7         3  B     0.3     0.4
    8         4  B     0.4     0.5
    

    【讨论】:

      猜你喜欢
      • 2018-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-12
      • 1970-01-01
      • 2018-06-17
      • 2018-06-23
      • 2018-12-21
      相关资源
      最近更新 更多