我想获取每列所有行具有相同值的列的名称。
我的数据:
A B C D
0 1 hi 2 a
1 3 hi 2 b
2 4 hi 2 c
期望的输出:
['B', 'C']
代码:
import pandas as pd
d = {'A': [1,3,4], 'B': ['hi','hi','hi'], 'C': [2,2,2], 'D': ['a','b','c']}
df = pd.DataFrame(data=d)
我一直在玩df.columns
和.any()
,但无法弄清楚如何做到这一点。
答案 0 :(得分:3)
解决方案1:
c = [c for c in df.columns if len(set(df[c])) == 1]
print (c)
['B', 'C']
解决方案2:
c = df.columns[df.eq(df.iloc[0]).all()].tolist()
print (c)
['B', 'C']
解决方案2的说明:
首先使用DataFrame.eq
...
print (df.eq(df.iloc[0]))
A B C D
0 True True True True
1 False True True False
2 False True True False
...然后使用DataFrame.all
...
True
print (df.eq(df.iloc[0]).all())
A False
B True
C True
D False
dtype: bool
...最后过滤列'结果为True的名称:
print (df.columns[df.eq(df.iloc[0]).all()])
Index(['B', 'C'], dtype='object')
<强>计时强>:
np.random.seed(100)
df = pd.DataFrame(np.random.randint(10, size=(1000,100)))
df[np.random.randint(100, size=20)] = 100
print (df)
# Solution 1 (second-fastest):
In [243]: %timeit ([c for c in df.columns if len(set(df[c])) == 1])
3.59 ms ± 43.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
# Solution 2 (fastest):
In [244]: %timeit df.columns[df.eq(df.iloc[0]).all()].tolist()
1.62 ms ± 13.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
#Mohamed Thasin ah solution
In [245]: %timeit ([col for col in df.columns if len(df[col].unique())==1])
6.8 ms ± 352 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
#jpp solution
In [246]: %%timeit
...: vals = df.apply(set, axis=0)
...: res = vals[vals.map(len) == 1].index
...:
5.59 ms ± 64.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
#smci solution 1
In [275]: %timeit df.columns[ df.nunique()==1 ]
11 ms ± 105 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
#smci solution 2
In [276]: %timeit [col for col in df.columns if not df[col].is_unique]
9.25 ms ± 80 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
#smci solution 3
In [277]: %timeit df.columns[ df.apply(lambda col: not col.is_unique) ]
11.1 ms ± 511 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
答案 1 :(得分:3)
pandas有两个不太知名的内置词:is_unique
...
['Apple','Apricot','Banana','Clementine','Orange','Pear','Pineapple']
......还有nunique()
:
df.columns[ df.apply(lambda col: not col.is_unique) ]
Index(['B', 'C'], dtype='object')
# or
[col for col in df.columns if not df[col].is_unique]
['B', 'C']
# or (faster)
from operator import attrgetter
df.columns[ df.apply(attrgetter('is_unique')) == False ]
Index(['B', 'C'], dtype='object')
(它是最干净的代码,但不是最快的代码)
(PS我不知道为什么我们必须反转df.columns[ df.nunique()==1 ]
Index(['B', 'C'], dtype='object')
,对我来说似乎不对)
答案 2 :(得分:2)
试试这个,
print [col for col in df.columns if len(df[col].unique())==1]
输出:
['B', 'C']
答案 3 :(得分:1)
您可以使用set
并在系列中应用过滤器:
vals = df.apply(set, axis=0)
res = vals[vals.map(len) == 1].index
print(res)
Index(['B', 'C'], dtype='object')
如果列表输出很重要,请使用res.tolist()
。