如何创建一个列,该列是另一列的移位版本,忽略 pandas 中的重复项?
How to create a column which is a shifted version of another column, disregarding duplicates in pandas?
我有一个 df:
import pandas as pd
import numpy as np
df = pd.DataFrame({
'a': [1, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 7, 8],
})
a
0 1
1 2
2 3
3 3
4 3
5 4
6 4
7 5
8 5
9 5
10 6
11 7
12 8
我需要创建 b
,它是 a
的“移位”,这样 b 中的每个条目都将是 a 中最接近的条目,它不是重复的,并且低于那个条目。
所需输出:
a b
0 1 2
1 2 3
2 3 4
3 3 4
4 3 4
5 4 5
6 4 5
7 5 6
8 5 6
9 5 6
10 6 7
11 7 8
12 8 nan
看起来像是 cumsum
、shift
、mask
的某种组合,但我不能完全将它们放在一起。也许是别的原因。
让我们尝试 map
唯一值:
s = df['a'].drop_duplicates()
df['b'] = df['a'].map(pd.Series(s.shift(-1).values,s))
输出:
a b
0 1 2.0
1 2 3.0
2 3 4.0
3 3 4.0
4 3 4.0
5 4 5.0
6 4 5.0
7 5 6.0
8 5 6.0
9 5 6.0
10 6 7.0
11 7 8.0
12 8 NaN
你可以试试:
df['b'] = df['a'].where(~df['a'].duplicated(keep='first')).bfill().shift(-1)
输出:
a b
0 1 2.0
1 2 3.0
2 3 4.0
3 3 4.0
4 3 4.0
5 4 5.0
6 4 5.0
7 5 6.0
8 5 6.0
9 5 6.0
10 6 7.0
11 7 8.0
12 8 NaN
详情:
我的方法是在 a
中找到重复值,然后使用下一个未屏蔽的值进行掩码和填充,然后移动系列 -1
.
如果只是根据你展示的样本数据
df['b'] = (df['a'].add(1)).where(df['a'].add(1).isin(df['a']))
df
Out[404]:
a b
0 1 2.0
1 2 3.0
2 3 4.0
3 3 4.0
4 3 4.0
5 4 5.0
6 4 5.0
7 5 6.0
8 5 6.0
9 5 6.0
10 6 7.0
11 7 8.0
12 8 NaN
如果没有
df['b'] = df.a.map(dict(zip(df.a.unique()[:-1],df.a.unique()[1:])))
我有一个 df:
import pandas as pd
import numpy as np
df = pd.DataFrame({
'a': [1, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 7, 8],
})
a 0 1 1 2 2 3 3 3 4 3 5 4 6 4 7 5 8 5 9 5 10 6 11 7 12 8
我需要创建 b
,它是 a
的“移位”,这样 b 中的每个条目都将是 a 中最接近的条目,它不是重复的,并且低于那个条目。
所需输出:
a b 0 1 2 1 2 3 2 3 4 3 3 4 4 3 4 5 4 5 6 4 5 7 5 6 8 5 6 9 5 6 10 6 7 11 7 8 12 8 nan
看起来像是 cumsum
、shift
、mask
的某种组合,但我不能完全将它们放在一起。也许是别的原因。
让我们尝试 map
唯一值:
s = df['a'].drop_duplicates()
df['b'] = df['a'].map(pd.Series(s.shift(-1).values,s))
输出:
a b
0 1 2.0
1 2 3.0
2 3 4.0
3 3 4.0
4 3 4.0
5 4 5.0
6 4 5.0
7 5 6.0
8 5 6.0
9 5 6.0
10 6 7.0
11 7 8.0
12 8 NaN
你可以试试:
df['b'] = df['a'].where(~df['a'].duplicated(keep='first')).bfill().shift(-1)
输出:
a b
0 1 2.0
1 2 3.0
2 3 4.0
3 3 4.0
4 3 4.0
5 4 5.0
6 4 5.0
7 5 6.0
8 5 6.0
9 5 6.0
10 6 7.0
11 7 8.0
12 8 NaN
详情:
我的方法是在 a
中找到重复值,然后使用下一个未屏蔽的值进行掩码和填充,然后移动系列 -1
.
如果只是根据你展示的样本数据
df['b'] = (df['a'].add(1)).where(df['a'].add(1).isin(df['a']))
df
Out[404]:
a b
0 1 2.0
1 2 3.0
2 3 4.0
3 3 4.0
4 3 4.0
5 4 5.0
6 4 5.0
7 5 6.0
8 5 6.0
9 5 6.0
10 6 7.0
11 7 8.0
12 8 NaN
如果没有
df['b'] = df.a.map(dict(zip(df.a.unique()[:-1],df.a.unique()[1:])))