繁体   English   中英

pandas groupby 中的条件赋值

[英]Conditional assign in pandas groupby

假设我在下面有df

df = pd.DataFrame({
    'ID': ['a', 'b', 'b', 'c', 'c', 'c', 'd', 'd', 'd', 'd'],
    'V': np.array(range(0,10))
})

我想对groupby变量进行ID并将值分配给新列X取决于 (1) 每个组的大小以及每行是否是顶部 ( T )、“中间”(更像是在顶部和底部之间) ( M ) 或底部 ( B ) 行。 如果组中只有一行,则分配的值为N 在这种情况下,结果将如下所示:

    ID  V   X
0   a   0   N
1   b   1   T
2   b   2   B
3   c   3   T
4   c   4   M
5   c   5   B
6   d   6   T
7   d   7   M
8   d   8   M
9   d   9   B

我可以使用类似的东西逐步执行此操作(对于T案例):

df.join(df.groupby('ID').filter(lambda x: len(x)>1).groupby('ID').head(1).assign(X='T').X, how='left')

但这感觉像是一个糟糕的解决方案。 我宁愿在一个 go 中完成所有工作。 有任何想法吗?

从您的逻辑来看,这很简单:

groups = df.groupby('ID')
first = groups['V'].head(1).index
last = groups['V'].tail(1).index

# the default middle values
df['X'] = 'M'

# the top and bottom values
df.loc[first, 'X'] = 'T'
df.loc[last, 'X'] = 'B'

# the unique values
ones = groups['V'].transform('size') == 1
df.loc[ones, 'X'] = 'N'

Output:

  ID  V  X
0  a  0  N
1  b  1  T
2  b  2  B
3  c  3  T
4  c  4  M
5  c  5  B
6  d  6  T
7  d  7  M
8  d  8  M
9  d  9  B

解决此问题的一种方法是将每行的 ID 与其之前/之后的 ID 进行比较。

例如:

df["top"] = df.ID != df.shift().ID
df["bottom"] = df.ID != df.shift(-1).ID
df["mid"] = (df.ID == df.shift(-1).ID) & (df.ID == df.shift(1).ID)

这导致:

    ID  V   bottom  top mid
0   a   0   True    True    False
1   b   1   False   True    False
2   b   2   True    False   False
3   c   3   False   True    False
4   c   4   False   False   True
5   c   5   True    False   False
6   d   6   False   True    False
7   d   7   False   False   True
8   d   8   False   False   True
9   d   9   True    False   False

您现在可以使用您想要创建 T/B/M/N 列的任何逻辑:

df.loc[df.bottom & (~df.mid), "V"] = "B"
df.loc[df.top & (~df.mid), "V"] = "T"
df.loc[df.mid, "V"] = "M"
df.loc[df.bottom & df.top, "V"] = "N"

df[["ID", "V"]]

结果是:

    ID  V
0   a   N
1   b   T
2   b   B
3   c   T
4   c   M
5   c   B
6   d   T
7   d   M
8   d   M
9   d   B

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM