Python 将值替换为下一个唯一的值

Python 将值替换为下一个唯一的值,python,pandas,Python,Pandas,在我的数据框中,我有一列非唯一值 我想添加第二列,其中包含下一个唯一值 i、 e 我如何使用熊猫来实现这一点 我将澄清我的意思,我希望每一行包含下一个不同于该行的值 我希望我现在能更好地解释我自己 设置 添加了具有多个群集的附加数据 df = pd.DataFrame({'col': [*map(int, '1552554442')]}) 两种解释 当存在不连续的簇时,我们必须考虑。 df col 0 1 # First instance of `1` Next

在我的数据框中,我有一列非唯一值 我想添加第二列,其中包含下一个唯一值 i、 e


我如何使用熊猫来实现这一点

  • 我将澄清我的意思,我希望每一行包含下一个不同于该行的值 我希望我现在能更好地解释我自己
设置 添加了具有多个群集的附加数据

df = pd.DataFrame({'col': [*map(int, '1552554442')]})

两种解释 当存在不连续的簇

时,我们必须考虑。
df

   col   
0    1   # First instance of `1` Next unique is `5`
1    5   # First instance of `5` Next unique is `2`
2    5   #                       Next unique is `2`
3    2   # First instance of `2` Next unique is `4` because `5` is not new
4    5   #                       Next unique is `4`
5    5   #                       Next unique is `4`
6    4   # First instance of `4` Next unique is null
7    4   # First instance of `4` Next unique is null
8    4   # First instance of `4` Next unique is null
9    2   # Second time seen `2` Should Next unique be null or what it was before `4`
允许回顾 使用
factorize
并添加
1
。这在很大程度上符合文的回答精神

i, u = df.col.factorize()
u_ = np.append(u, -1)  # Append an integer value to represent null

df.assign(addedcol=u_[i + 1])

   col  addedcol
0    1         5
1    5         2
2    5         2
3    2         4
4    5         2
5    5         2
6    4        -1
7    4        -1
8    4        -1
9    2         4

只向前 与之前类似,只是我们将跟踪累计最大因式分解值

i, u = df.col.factorize()
u_ = np.append(u, -1)  # Append an integer value to represent null

x = np.maximum.accumulate(i)

df.assign(addedcol=u_[x + 1])

   col  addedcol
0    1         5
1    5         2
2    5         2
3    2         4
4    5         4
5    5         4
6    4        -1
7    4        -1
8    4        -1
9    2        -1
您会注意到差异在最后一个值中。当我们只能向前看时,我们看到没有下一个唯一值。

Setup 添加了具有多个群集的附加数据

df = pd.DataFrame({'col': [*map(int, '1552554442')]})

两种解释 当存在不连续的簇

时,我们必须考虑。
df

   col   
0    1   # First instance of `1` Next unique is `5`
1    5   # First instance of `5` Next unique is `2`
2    5   #                       Next unique is `2`
3    2   # First instance of `2` Next unique is `4` because `5` is not new
4    5   #                       Next unique is `4`
5    5   #                       Next unique is `4`
6    4   # First instance of `4` Next unique is null
7    4   # First instance of `4` Next unique is null
8    4   # First instance of `4` Next unique is null
9    2   # Second time seen `2` Should Next unique be null or what it was before `4`
允许回顾 使用
factorize
并添加
1
。这在很大程度上符合文的回答精神

i, u = df.col.factorize()
u_ = np.append(u, -1)  # Append an integer value to represent null

df.assign(addedcol=u_[i + 1])

   col  addedcol
0    1         5
1    5         2
2    5         2
3    2         4
4    5         2
5    5         2
6    4        -1
7    4        -1
8    4        -1
9    2         4

只向前 与之前类似,只是我们将跟踪累计最大因式分解值

i, u = df.col.factorize()
u_ = np.append(u, -1)  # Append an integer value to represent null

x = np.maximum.accumulate(i)

df.assign(addedcol=u_[x + 1])

   col  addedcol
0    1         5
1    5         2
2    5         2
3    2         4
4    5         4
5    5         4
6    4        -1
7    4        -1
8    4        -1
9    2        -1

您会注意到差异在最后一个值中。当我们只能向前看时,我们看到没有下一个唯一的值。

使用
factorize

s=pd.factorize(df.col)[0]
pd.Series(s+1).map(dict(zip(s,df.col)))
Out[242]: 
0    5.0
1    2.0
2    2.0
3    NaN
dtype: float64

#df['newadd']=pd.Series(s+1).map(dict(zip(s,df.col))).values
在Mart的情况下

s=df.col.diff().ne(0).cumsum()
(s+1).map(dict(zip(s,df.col)))
Out[260]: 
0    5.0
1    2.0
2    2.0
3    4.0
4    4.0
5    5.0
6    NaN
7    NaN
Name: col, dtype: float64

使用
factorize

s=pd.factorize(df.col)[0]
pd.Series(s+1).map(dict(zip(s,df.col)))
Out[242]: 
0    5.0
1    2.0
2    2.0
3    NaN
dtype: float64

#df['newadd']=pd.Series(s+1).map(dict(zip(s,df.col))).values
在Mart的情况下

s=df.col.diff().ne(0).cumsum()
(s+1).map(dict(zip(s,df.col)))
Out[260]: 
0    5.0
1    2.0
2    2.0
3    4.0
4    4.0
5    5.0
6    NaN
7    NaN
Name: col, dtype: float64

IIUC,需要与当前值不同的下一个值

df.loc[:, 'col2'] = df.drop_duplicates().shift(-1).col
df['col2'].ffill(inplace=True)

    col col2
0   1   5.0
1   5   2.0
2   5   2.0
3   2   2.0
(请注意,最后的2.0值并不重要)。根据@MartijnPieters的建议

df['col2'] = df['col2'].astype(int)
如果需要,可以将值还原为原始整数


从@piRSquared添加另一个好的解决方案

df.assign(addedcol=df.index.to_series().shift(-1).map(df.col.drop_duplicates()).bfill())

    col addedcol
0   1   5.0
1   5   2.0
2   5   2.0
3   2   NaN

另一个例子是,如果
df

    col
0   1
1   5
2   5
3   2
4   3
5   3
6   10
7   9
然后

屈服

    col col2
0   1   5.0
1   5   2.0
2   5   2.0
3   2   3.0
4   3   10.0
5   3   10.0
6   10  9.0
7   9   9.0

IIUC,需要与当前值不同的下一个值

df.loc[:, 'col2'] = df.drop_duplicates().shift(-1).col
df['col2'].ffill(inplace=True)

    col col2
0   1   5.0
1   5   2.0
2   5   2.0
3   2   2.0
(请注意,最后的2.0值并不重要)。根据@MartijnPieters的建议

df['col2'] = df['col2'].astype(int)
如果需要,可以将值还原为原始整数


从@piRSquared添加另一个好的解决方案

df.assign(addedcol=df.index.to_series().shift(-1).map(df.col.drop_duplicates()).bfill())

    col addedcol
0   1   5.0
1   5   2.0
2   5   2.0
3   2   NaN

另一个例子是,如果
df

    col
0   1
1   5
2   5
3   2
4   3
5   3
6   10
7   9
然后

屈服

    col col2
0   1   5.0
1   5   2.0
2   5   2.0
3   2   3.0
4   3   10.0
5   3   10.0
6   10  9.0
7   9   9.0


我不明白;
5
如何成为
[1 5 5 2]
1
的下一个唯一值?你能一步一步地把它分解吗?也许你可以问一下为什么第0行用5填充?由于5不是唯一的,在第一行中,出现1,下一个唯一值是5,在第二行中,下一个唯一(不同)值是2,在第三行中,2仍然是下一个唯一值因此,@freakazoid通常耐心和解释要走很长的路。我以为你有打字错误。但现在我意识到你想要的是一个结果,却没有解释如何得到它,也没有展示你的尝试。请注意,我们没有报酬回答您的问题。我们是喜欢帮助他人的编程爱好者。当你认为我们的回答是理所当然的时候,这会变得无礼,人们也不太愿意帮助你。@piRSquared我意识到,由于这些回答,我一定没有正确地解释自己,所以我编辑了我的问题,我希望现在措辞更恰当一些,我不明白;
5
如何成为
[1 5 5 2]
1
的下一个唯一值?你能一步一步地把它分解吗?也许你可以问一下为什么第0行用5填充?由于5不是唯一的,在第一行中,出现1,下一个唯一值是5,在第二行中,下一个唯一(不同)值是2,在第三行中,2仍然是下一个唯一值因此,@freakazoid通常耐心和解释要走很长的路。我以为你有打字错误。但现在我意识到你想要的是一个结果,却没有解释如何得到它,也没有展示你的尝试。请注意,我们没有报酬回答您的问题。我们是喜欢帮助他人的编程爱好者。当你认为我们的回答是理所当然的时候,这就变得无礼,人们也不太愿意帮助你了。@piRSquared我意识到由于我的回答我一定没有正确地解释自己,所以我编辑了我的问题,我希望它现在的措辞更好注意,在第二行我希望出现2,而不是5(2是下一个唯一的值)如果一个值有多个簇,则此操作将失败。说<代码> Pd。DataFrame({ COL):(1, 5, 5,2, 2, 4,5, 5)} /代码>由于该系列中的<代码> 4 < /代码>是<代码>标签数组中的最高值,在中间你会得到一个<代码>楠< /代码>。<代码>差异()(NE(0))。我的方法与@Wen类似,请注意,在第二行中,我希望显示2,而不是5(2是下一个唯一值),如果一个值有多个簇,则此操作将失败。说<代码> Pd。DataFrame({ COL):(1, 5, 5,2, 2, 4,5, 5)} /代码>由于该系列中的<代码> 4 < /代码>是<代码>标签数组中的最高值,在中间你会得到一个<代码>楠< /代码>。<代码>差异()(NE(0))。我的方法类似@WenYou似乎删除了第一个示例中的第3行。@MartiInputers复制/粘贴错误,没有删除该行:p(并且一旦NAs消失,在正向填充后,可能
col2
可以转换回相同的int-dtype)。是的,我检查了您的代码是否会删除该行(这会令人惊讶)如果一个值有多个簇,则此操作将失败。假设
pd.DataFrame({'col':[1,5,5,2,2,4,5,5]})
。您似乎删除了第一个示例中的第3行。@MartijnPieters复制/粘贴错误,没有删除行:p(一旦NAs消失,在正向填充后,可能
col2
可以转换回相同的int数据类型)。是的,我检查了您的代码是否会删除该行(这将是令人惊讶的)如果一个值有多个集群,这将失败。比如说
pd.DataFrame({'col':[1,5,5,2,2,4,5,5]})