获取pandas中其列中具有相同值的行

时间:2014-01-20 10:27:00

标签: python pandas dataframe

在pandas中,给定一个DataFrame D:

+-----+--------+--------+--------+   
|     |    1   |    2   |    3   |
+-----+--------+--------+--------+
|  0  | apple  | banana | banana |
|  1  | orange | orange | orange |
|  2  | banana | apple  | orange |
|  3  | NaN    | NaN    | NaN    |
|  4  | apple  | apple  | apple  |
+-----+--------+--------+--------+

当有三列或更多列时,如何返回其所有列中具有相同内容的行,以便它返回:

+-----+--------+--------+--------+   
|     |    1   |    2   |    3   |
+-----+--------+--------+--------+
|  1  | orange | orange | orange |
|  4  | apple  | apple  | apple  |
+-----+--------+--------+--------+

请注意,当所有值均为NaN时,它会跳过行。

如果这只是两列,我通常会D[D[1]==D[2]],但我不知道如何对超过2列的DataFrame进行推广。

6 个答案:

答案 0 :(得分:13)

我的参赛作品:

>>> df
        0       1       2
0   apple  banana  banana
1  orange  orange  orange
2  banana   apple  orange
3     NaN     NaN     NaN
4   apple   apple   apple

[5 rows x 3 columns]
>>> df[df.apply(pd.Series.nunique, axis=1) == 1]
        0       1       2
1  orange  orange  orange
4   apple   apple   apple

[2 rows x 3 columns]

这是有效的,因为在行上调用pd.Series.nunique会给出:

>>> df.apply(pd.Series.nunique, axis=1)
0    2
1    1
2    3
3    0
4    1
dtype: int64

注意:但是,这会保留看似[nan, nan, apple][nan, apple, apple]的行。通常我想要那个,但这可能是你用例的错误答案。

答案 1 :(得分:11)

类似于Andy Hayden的回答,检查min是否等于max(然后行元素都是重复的):

df[df.apply(lambda x: min(x) == max(x), 1)]

答案 2 :(得分:6)

我会检查每行是否为equal第一个元素:

In [11]: df.eq(df[1], axis='index')  # Note: funky broadcasting with df == df[1]
Out[11]: 
      1      2      3
0  True  False  False
1  True   True   True
2  True  False  False
3  True   True   True
4  True   True   True

[5 rows x 3 columns]

如果行中的所有内容都为True,则行中的所有元素都相同:

In [12]: df.eq(df[1], axis='index').all(1)
Out[12]: 
0    False
1     True
2    False
3     True
4     True
dtype: bool

仅限于行和可选的dropna:

In [13]: df[df.eq(df[1], axis='index').all(1)]
Out[13]: 
        1       2       3
1  orange  orange  orange
3     NaN     NaN     NaN
4   apple   apple   apple

[3 rows x 3 columns]

In [14]: df[df.eq(df[1], axis='index').all(1)].dropna()
Out[14]: 
        1       2       3
1  orange  orange  orange
4   apple   apple   apple

[2 rows x 3 columns]

答案 3 :(得分:1)

基于DSM's answer,您可能需要此方法:

import pandas as pd

def filter_data(df):
    df = df.dropna(inplace = True)
    df = df[df.apply(pd.Series.nunique, axis=1)]
    return df

答案 4 :(得分:1)

在较新版本的熊猫中,您可以使用nunique

In [815]: df[df.nunique(1).eq(1)]
Out[815]:
        0       1       2
1  orange  orange  orange
4   apple   apple   apple

详细信息

In [816]: df
Out[816]:
        0       1       2
0   apple  banana  banana
1  orange  orange  orange
2  banana   apple  orange
3     NaN     NaN     NaN
4   apple   apple   apple

In [817]: df.nunique(1)
Out[817]:
0    2
1    1
2    3
3    0
4    1
dtype: int64

In [818]: df.nunique(1).eq(1)
Out[818]:
0    False
1     True
2    False
3    False
4     True
dtype: bool

答案 5 :(得分:0)

您可以使用set创建符合规则的索引位置列表,然后使用该列表对数据框进行切片。例如:

import pandas as pd
import numpy as np

D = {0  : ['apple' , 'banana', 'banana'], 1 : ['orange', 'orange', 'orange'], 2: ['banana', 'apple', 'orange'], 3: [np.nan, np.nan, np.nan], 4 : ['apple', 'apple', 'apple']} 
DF = pd.DataFrame(D).T

Equal = [row for row in DF.index if len(set(DF.iloc[row])) == 1]

DF.iloc[Equal]

请注意,如果不必明确排除缺失值,则会排除缺失值行。这是因为由于系列中缺失值的性质。