Панды: Получить все столбцы, которые имеют постоянное значение - PullRequest
0 голосов
/ 29 мая 2018

Я хочу получить имена столбцов, которые имеют одинаковые значения во всех строках для каждого столбца.

Мои данные:

   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(), но не могу понять, как это сделать.

Ответы [ 4 ]

0 голосов
/ 29 мая 2018

панд имеет два не очень известных встроенных объекта: is_unique ...

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')

... а также nunique():

df.columns[ df.nunique()==1 ]
Index(['B', 'C'], dtype='object')

(это самый чистый код, но не самый быстрый)

(PS Я не уверен, почему мы должны инвертировать is_unique, мне кажется, это неправильно)

0 голосов
/ 29 мая 2018

попробуйте это,

print [col for col in df.columns if len(df[col].unique())==1]

Вывод:

['B', 'C']
0 голосов
/ 29 мая 2018

Вы можете использовать set и применить фильтр к серии:

vals = df.apply(set, axis=0)
res = vals[vals.map(len) == 1].index

print(res)

Index(['B', 'C'], dtype='object')

Используйте res.tolist(), если важен вывод списка.

0 голосов
/ 29 мая 2018

Решение 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

... затем проверьте все столбцы True с DataFrame.all ...

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...