在熊猫中查找第一个非NaN值

时间:2019-01-22 01:58:37

标签: python pandas pandas-groupby

我有一个这样的熊猫数据框

|user_id|value|No|
|:-:|:-:|:-:|
|id1|100|1|
|id1|200|2|
|id1|250|3|
|id2|NaN|1|
|id2|100|2|
|id3|400|1|
|id3|NaN|2|
|id3|200|3|
|id4|NaN|1|
|id4|NaN|2|
|id4|300|3|.

然后我想要以下数据集:

|user_id|value|No|NewNo|
|:-:|:-:|:-:|:-:|
|id1|100|1|1|
|id1|200|2|2|
|id1|250|3|3|
|id2|100|2|1|
|id3|400|1|1|
|id3|NaN|2|2|
|id3|200|3|3|
|id4|300|3|1|

即,我要删除NaN值,以使user_id的第一个值不是NaN值。谢谢。

2 个答案:

答案 0 :(得分:3)

您可以分组并向前填充值列。转换后的数据中的空值表示每个组从头开始的空值。筛选出空的行

df2 = df[df.groupby('user_id').value.ffill().apply(pd.notnull)].copy()
# application of copy here creates a new data frame and allows us to assign
# values to the result (df2). This is needed to create the column `NewNo` 
# in the next & final step
# df2 outputs:
   user_id  value  No
0    'id1'  100.0   1
1    'id1'  200.0   2
2    'id1'  250.0   3
4    'id2'  100.0   2
5    'id3'  400.0   1
6    'id3'    NaN   2
7    'id3'  200.0   3
10   'id4'  300.0   3

使用组内的排名生成NewNo列。

df2['NewNo'] = df2.groupby('user_id').No.rank()

# df2 outputs:

   user_id  value  No  NewNo
0    'id1'  100.0   1    1.0
1    'id1'  200.0   2    2.0
2    'id1'  250.0   3    3.0
4    'id2'  100.0   2    1.0
5    'id3'  400.0   1    1.0
6    'id3'    NaN   2    2.0
7    'id3'  200.0   3    3.0
10   'id4'  300.0   3    1.0

答案 1 :(得分:0)

groupby + first_valid_index + cumcount

您可以按组计算第一个非空值的索引,然后使用布尔索引:

# use transform to align groupwise first_valid_index with dataframe
firsts = df.groupby('user_id')['value'].transform(pd.Series.first_valid_index)

# apply Boolean filter
res = df[df.index >= firsts]

# use groupby + cumcount to add groupwise labels
res['NewNo'] = res.groupby('user_id').cumcount() + 1

print(res)

   user_id  value  No  NewNo
0      id1  100.0   1      1
1      id1  200.0   2      2
2      id1  250.0   3      3
4      id2  100.0   2      1
5      id3  400.0   1      1
6      id3    NaN   2      2
7      id3  200.0   3      3
10     id4  300.0   3      1