我有一个pandas数据框,如下所示。没有["sente"]
值的所有行都包含更多信息,但它们尚未与["sente"]
相关联。
id pos value sente
1 a I 21
2 b have 21
3 b a 21
4 a cat 21
5 d ! 21
6 cat N Nan
7 a My 22
8 a cat 22
9 b is 22
10 a cute 22
11 d . 22
12 cat N NaN
13 cute M NaN
现在我希望["sente"]
中没有值的每一行从上面的行中获取其值。然后,我希望按["sente"]
对所有内容进行分组,并创建一个新列,其中包含来自行的内容,但["sente"]
中没有值。
sente pos value content
21 a,b,b,a,d I have a cat ! 'cat,N'
22 a,a,b,a,d My cat is cute . 'cat,N','cute,M'
这是我的第一步:
df.loc[(df['sente'] != df["sente"].shift(-1) & df["sente"] == Nan) , "sente"] = df["sente"].shift(+1)
但它只适用于一个额外的行,如果有2个或更多则不行。
这就像我想要的那样将一列分组:
df.groupby(["sente"])['value'].apply(lambda x: " ".join()
但是对于更多列,它并不像我想要的那样工作:
df.groupby(["sente"]).agr(lambda x: ",".join()
有没有办法在不使用堆栈功能的情况下执行此操作?
答案 0 :(得分:1)
使用:
#check NaNs values to boolean mask
m = df['sente'].isnull()
#new column of joined columns only if mask
df['contant'] = np.where(m, df['pos'] + ',' + df['value'], np.nan)
#replace to NaNs by mask
df[['pos', 'value']] = df[['pos', 'value']].mask(m)
print (df)
id pos value sente contant
0 1 a I 21.0 NaN
1 2 b have 21.0 NaN
2 3 b a 21.0 NaN
3 4 a cat 21.0 NaN
4 5 d ! 21.0 NaN
5 6 NaN NaN NaN cat,N
6 7 a My 22.0 NaN
7 8 a cat 22.0 NaN
8 9 b is 22.0 NaN
9 10 a cute 22.0 NaN
10 11 d . 22.0 NaN
11 12 NaN NaN NaN cat,N
12 13 NaN NaN NaN cute,M
最后通过向前填充NaN
和ffill
并join
移除NaN
来替换dropna
:
df1 = df.groupby(df["sente"].ffill()).agg(lambda x: " ".join(x.dropna()))
print (df1)
pos value contant
sente
21.0 a b b a d I have a cat ! cat,N
22.0 a a b a d My cat is cute . cat,N cute,M