pandas 数据框替换问题

1 投票
3 回答
934 浏览
提问于 2025-04-17 16:22

我有一个数据框(df)

df:
  date     shares  symbol  date2
0 20120614  1100   AAT.N   NaN
1 20120615  1100   AAT.N   NaN
2 20120616  1100   AAT.N   NaN
3 20120617  1100   AAT.N   NaN
4 20030405  800    ABT.N   NaN
5 20030406  800    ABT.N   NaN
6 20030407  800    ABT.N   NaN
...

#This is what I want:
df:
  date     shares  symbol  date2
0 20120614  1100   AAT.N   20120615
1 20120615  1100   AAT.N   20120616
2 20120616  1100   AAT.N   20120617
3 20120617  1100   AAT.N   NaN
4 20030405  800    ABT.N   20030406
5 20030406  800    ABT.N   20030407
6 20030407  800    ABT.N   NaN
...

我想把 df.ix[0]['date2'] 替换成 df.ix[1]['date2'],这个操作是针对每个符号(symbol)进行的,因为符号在数据框中是变化的,所以不能直接对整个数据框进行操作。

我打算通过循环来实现,如果当前的符号和下一个符号匹配的话:

df.ix[i]['symbol'] == df.ix[i+1]['symbol']

我就把 NaN 替换成对应的日期。

我试过:

df.ix[i]['date2'] = df.ix[i+1]['date']  ##This failed.

然后我又试了:

a = df.ix[i+1]['date']
df.replace({'date2': i}, a)
###This failed as well

在这里有没有什么建议呢?

1) 最好的方法来完成这个任务是什么?

2) 基础问题:如何在 pandas 数据框中替换 NaN(或者其他数字)?

谢谢。

3 个回答

0

我可能会这样做:

>>> df
       date  shares symbol  date2
0  20120614    1100  AAT.N    NaN
1  20120615    1100  AAT.N    NaN
2  20120616    1100  AAT.N    NaN
3  20120617    1100  AAT.N    NaN
4  20030405     800  ABT.N    NaN
5  20030406     800  ABT.N    NaN
6  20030407     800  ABT.N    NaN
>>> same_symbols = df['symbol'] == df['symbol'].shift(-1)
>>> df['date2'][same_symbols] = df['date'].shift(-1)
>>> df
       date  shares symbol     date2
0  20120614    1100  AAT.N  20120615
1  20120615    1100  AAT.N  20120616
2  20120616    1100  AAT.N  20120617
3  20120617    1100  AAT.N       NaN
4  20030405     800  ABT.N  20030406
5  20030406     800  ABT.N  20030407
6  20030407     800  ABT.N       NaN

这段代码是用来找出每一行之间相同的符号的位置:

>>> same_symbols
0     True
1     True
2     True
3    False
4     True
5     True
6    False
Name: symbol, Dtype: bool

然后在这些位置上应用偏移的日期:

>>> df['date'].shift(-1)
0    20120615
1    20120616
2    20120617
3    20030405
4    20030406
5    20030407
6         NaN
Name: date, Dtype: float64

这段代码假设符号数据是连续的,并且已经排好序(如果不是这样的话,调整一下也很简单)。

另外,你也可以使用 groupby,然后对每一组进行操作,最后再把结果组合起来。

1

为了和DSM的布尔解决方案进行比较,这里有一个简单快捷的groupby解决方案!

grouped = df.groupby('symbol')
for _, group in grouped:
    df1['date2'][group.index] = group.shift(-1)['date']
3

这里有一个一行代码的解决方案,可能是最“简单明了”的:

In [8]: df['date2'] = df.groupby('symbol').apply(lambda x: x['date'].shift(-1))

In [9]: df
Out[9]:
       date  shares symbol     date2
0  20120614    1100  AAT.N  20120615
1  20120615    1100  AAT.N  20120616
2  20120616    1100  AAT.N  20120617
3  20120617    1100  AAT.N       NaN
4  20030405     800  ABT.N  20030406
5  20030406     800  ABT.N  20030407
6  20030407     800  ABT.N       NaN

撰写回答