pandas 根据上一组中的上一个值(如果存在)设置值

taor4pac  于 2023-03-06  发布在  其他
关注(0)|答案(2)|浏览(123)

假设我有这个:

df = pandas.DataFrame(
  [ dict(a=75, b=numpy.nan, d='2023-01-01 00:00')
  , dict(a=82, b=numpy.nan, d='2023-01-01 10:00')
  , dict(a=39, b=numpy.nan, d='2023-01-01 20:00')
  , dict(a=10, b=82       , d='2023-01-05 00:00')
  , dict(a=90, b=82       , d='2023-01-05 20:00')
  , dict(a=61, b=numpy.nan, d='2023-02-08 00:00')
  , dict(a=35, b=numpy.nan, d='2023-02-08 10:00')
  , dict(a=95, b=numpy.nan, d='2023-02-08 20:00')
  , dict(a=21, b=35       , d='2023-04-15 00:00')
  , dict(a=60, b=35       , d='2023-04-15 10:00')
  ])                                             
df['d'] = pandas.to_datetime(df['d'])            
df = df.set_index('d')                           
print(df)

其输出:

a     b
d
2023-01-01 00:00:00  75   NaN
2023-01-01 10:00:00  82   NaN
2023-01-01 20:00:00  39   NaN
2023-01-05 00:00:00  10  82.0
2023-01-05 20:00:00  90  82.0
2023-02-08 00:00:00  61   NaN
2023-02-08 10:00:00  35   NaN
2023-02-08 20:00:00  95   NaN
2023-04-15 00:00:00  21  35.0
2023-04-15 10:00:00  60  35.0

在现实生活中,我只有a列,我想要的输出在b列中。
此处,b等于a中的值,该值来自上一个可用日期10:00。日期不一定连续。上一个可用日期10:00处的值可能不存在,在这种情况下,b应为NaN。
从逻辑上讲,我会通过按日期分组并从前一组中提取值来解决这个问题。
如果不对每个(previous group, group)元组进行迭代或类似的操作,Pandas可以做到吗?
更一般地说,有没有Pandas成语来处理这些"从上一组中查找值"的情况?
我将在这里添加编辑的答案来显示额外的信息,不适合很好地在一个评论。
对于https://stackoverflow.com/a/75599866/3821009

df['c'] = df.groupby(df.index.date)['a'].shift() 
print(df)

产生:

a     b     c
d
2023-01-01 00:00:00  75   NaN   NaN
2023-01-01 10:00:00  82   NaN  75.0
2023-01-01 20:00:00  39   NaN  82.0
2023-01-05 00:00:00  10  82.0   NaN
2023-01-05 20:00:00  90  82.0  10.0
2023-02-08 00:00:00  61   NaN   NaN
2023-02-08 10:00:00  35   NaN  61.0
2023-02-08 20:00:00  95   NaN  35.0
2023-04-15 00:00:00  21  35.0   NaN
2023-04-15 10:00:00  60  35.0  21.0

所以这不是我想要的。

e3bfsja2

e3bfsja21#

总体思路是:
1.获取时间为10.00时的值
1.获取日期组ID
1.如果时间是有序的,则当前组ID仅比前一个组ID大1
1.使用组ID将上一个时间值Map到当前时间值

time = df.loc[df.index.time == pd.to_datetime('10:00:00').time(), 'a']
gid = df.groupby(df.index.date).ngroup()
df['c'] = gid.map(dict(zip(time.index.map(gid)+1, time)))
$ print(time)

d
2023-01-01 10:00:00    82
2023-02-08 10:00:00    35
2023-04-15 10:00:00    60
Name: a, dtype: int64

$ print(gid)

d
2023-01-01 00:00:00    0
2023-01-01 10:00:00    0
2023-01-01 20:00:00    0
2023-01-05 00:00:00    1
2023-01-05 20:00:00    1
2023-02-08 00:00:00    2
2023-02-08 10:00:00    2
2023-02-08 20:00:00    2
2023-04-15 00:00:00    3
2023-04-15 10:00:00    3
dtype: int64

$ print(df)

                      a     b     c
d
2023-01-01 00:00:00  75   NaN   NaN
2023-01-01 10:00:00  82   NaN   NaN
2023-01-01 20:00:00  39   NaN   NaN
2023-01-05 00:00:00  10  82.0  82.0
2023-01-05 20:00:00  90  82.0  82.0
2023-02-08 00:00:00  61   NaN   NaN
2023-02-08 10:00:00  35   NaN   NaN
2023-02-08 20:00:00  95   NaN   NaN
2023-04-15 00:00:00  21  35.0  35.0
2023-04-15 10:00:00  60  35.0  35.0
z9smfwbn

z9smfwbn2#

是的,我相信您可以将groupby()方法与shift()方法沿着使用来实现这一点。
你可以这样做,

df['b'] = df.groupby(df.index.date)['a'].shift()

这段代码获取一个数据表,并根据表中的日期将其分解为多个组。对于每个组,它查看“a”列中的值,并将其向下移动一行。
通过这样做,“b”列现在显示前一组中该组中每一行的“a”值。

相关问题