已更新
我有一个如下所示的df:
print(df)
id rank a
date
2000-01-01 1 1.0 0
2000-01-01 2 3.0 0
2000-01-01 3 2.0 0
2000-01-01 4 0.0 0
2000-01-02 1 2.0 0
2000-01-02 2 3.0 0
2000-01-02 3 2.0 0
2000-01-02 4 1.0 0
2000-01-03 1 3.0 0
2000-01-03 2 2.0 0
2000-01-03 3 1.0 0
2000-01-03 4 1.0 0
我想创建一个新变量a
,如果rank
与上个月相比有所变化,则该变量等于1。例如,在2000-01-01
中rank
是3.0,而在2000-01-02
中它变为2.0。我希望此更改与a
中的1对应,如果没有更改,请保持为0。我也想对id
进行分组。此外,等级在每个期间只能增加1。
预期产量
id rank a
date
2000-01-01 1 1.0 1
2000-01-01 2 3.0 1
2000-01-01 3 2.0 1
2000-01-01 4 0.0 1
2000-01-02 1 2.0 1
2000-01-02 2 3.0 0
2000-01-02 3 2.0 0
2000-01-02 4 1.0 1
2000-01-03 1 3.0 1
2000-01-03 2 2.0 1
2000-01-03 3 1.0 1
2000-01-03 4 1.0 0
任何帮助都会很棒!
答案 0 :(得分:4)
将Series.diff
与Series.abs
一起使用,如果可能的话,更像1
的地方使用Series.clip
:
df['a'] = df['rank'].diff().abs().clip(upper=1)
如果差异始终只有1
:
df['a'] = df['rank'].diff().abs()
如果需要将第一个值设置为0
:
df['a'] = df['rank'].diff().fillna(0).ne(0).astype(int)
修改后的答案:
df['a1'] = df.groupby('id')['rank'].diff().ne(0).astype(int)
print (df)
date id rank a a1
0 2000-01-01 1 1.0 1 1
1 2000-01-01 2 3.0 1 1
2 2000-01-01 3 2.0 1 1
3 2000-01-01 4 0.0 1 1
4 2000-01-02 1 2.0 1 1
5 2000-01-02 2 3.0 0 0
6 2000-01-02 3 2.0 0 0
7 2000-01-02 4 1.0 1 1
8 2000-01-03 1 3.0 1 1
9 2000-01-03 2 2.0 1 1
10 2000-01-03 3 1.0 1 1
11 2000-01-03 4 1.0 0 0
答案 1 :(得分:2)
使用shift
:
import pandas as pd
df = pd.DataFrame({"rank": [3.0, 2.0, 2.0, 2.0, 1.0]})
df['a'] = (df['rank'] - df['rank'].shift(1)).abs()
print(df)
输出:
rank a
0 3.0 NaN
1 2.0 1.0
2 2.0 0.0
3 2.0 0.0
4 1.0 1.0
编辑:
如果要用空字符串替换NaN
:
df['a'] = df['a'].fillna('').astype(str)
编辑2 :
使用np.where
,由于上面的代码段将产生实际的差异,因此使用此方法可为您带来1的差异,否则为0:
import pandas as pd
df = pd.DataFrame({"rank": [3.0, 12.0, 2.0, 2.0, 1.0]})
df['a'] = np.where((df['rank'] - df['rank'].shift(1)).abs() > 0, 1, 0)
print(df)
答案 2 :(得分:1)
您可以使用np.select
df0 = df.shift()
cond1 = df0['rank'].isnull() # to set first row nan
cond2 = df0['rank'] != df['rank']
df['a'] = np.select([cond1,cond2], [0,1], 0)
print(df)
答案 3 :(得分:0)
d['a'] = (d['rank'].shift() == d['rank']).map({True:0, False:1})
请注意,列a
的第一个元素是1
。不需要时将其删除。
希望对您有帮助。
答案 4 :(得分:0)
这也可以通过使用Series.diff()并将以下一系列布尔值直接转换为整数来完成:
df['a']=df['rank'].diff().eq(-1).astype(int)