我想从df
中的多个列中返回唯一行。问题是,如果它们没有出现在上一行中,则我想包含相同的一组值。这有点难以解释,所以我将显示它;
df = pd.DataFrame({
'Time' : ['2019-08-02 09:50:10.1','2019-08-02 09:50:10.2','2019-08-02 09:50:10.3','2019-08-02 09:50:10.4','2019-08-02 09:50:10.5','2019-08-02 09:50:10.6','2019-08-02 09:50:10.7','2019-08-02 09:50:10.8','2019-08-02 09:50:10.9','2019-08-02 09:50:11.0'],
'Code1' : ['A','A','B','B','C','C','A','A','B','B'],
'Code2' : ['B','B','A','A','B','B','B','B','A','A'],
'Code3' : [np.nan,np.nan,'C','C','A','A','C','C','C','C'],
})
df = df[df.iloc[:, 1:].shift().ne(df.iloc[:, 1:]).any(axis=1)].reset_index(drop = True)
预期输出:
Time Code1 Code2 Code3
0 2019-08-02 09:50:10.1 A B NaN
1 2019-08-02 09:50:10.3 B A C
2 2019-08-02 09:50:10.5 C B A
3 2019-08-02 09:50:10.7 A B C
4 2019-08-02 09:50:10.9 B A C
答案 0 :(得分:1)
首先,我们使用iloc
选择正确的列,然后使用shift
检查当前行是否不等于下一行。最后,我们在any
上使用axis=1 (columns)
。因为A B C
和B A C
不同,但是有C
共同点:
df[df.iloc[:, 1:].shift().ne(df.iloc[:, 1:]).any(axis=1)]
还是一样,但要简洁一点:
mask = df.iloc[:, 1:].shift().ne(df.iloc[:, 1:])
df[mask.any(axis=1)]
Time Code1 Code2 Code3
0 2019-08-02 09:50:10.1 A B C
2 2019-08-02 09:50:10.3 B A C
4 2019-08-02 09:50:10.5 C B A
6 2019-08-02 09:50:10.7 A B C
8 2019-08-02 09:50:10.9 B A C
答案 1 :(得分:1)
您可以为空值使用前哨值,然后对结果进行分组。
groupby
是shift-cumsum pattern的变体。
sentinel = 99999999
mask = df[cols].fillna(sentinel).ne(df[cols].fillna(sentinel).shift())
>>> df.groupby(
mask.any(axis=1).cumsum(),
sort=False,
as_index=False
).first()
Time Code1 Code2 Code3
0 2019-08-02 09:50:10.1 A B NaN
1 2019-08-02 09:50:10.3 B A C
2 2019-08-02 09:50:10.5 C B A
3 2019-08-02 09:50:10.7 A B C
4 2019-08-02 09:50:10.9 B A C