Ответ 1
Это работает:
df[df['A'].apply(lambda x: type(x)==str)]
Итак, DataFrame говорит:
>>> df = pd.DataFrame({
... 'A':[1,2,'Three',4],
... 'B':[1,'Two',3,4]})
>>> df
A B
0 1 1
1 2 Two
2 Three 3
3 4 4
Я хочу выбрать строки, тип данных которых для определенной строки определенного столбца имеет тип str
.
Например, я хочу выбрать строку, в которой type
данных в столбце A
есть str
.
поэтому он должен печатать что-то вроде:
A B
2 Three 3
Чей интуитивно понятный код будет выглядеть следующим образом:
df[type(df.A) == str]
Что явно не работает!
Спасибо, пожалуйста, помогите!
Это работает:
df[df['A'].apply(lambda x: type(x)==str)]
Вы можете сделать что-то похожее на то, что вы задаете с помощью
In [14]: df[pd.to_numeric(df.A, errors='coerce').isnull()]
Out[14]:
A B
2 Three 3
Почему только подобное? Поскольку Pandas хранит объекты в однородных столбцах (все записи в столбце одного типа). Несмотря на то, что вы построили DataFrame из гетерогенных типов, все они превращаются в столбцы каждый из самых низких общих знаменателей:
In [16]: df.A.dtype
Out[16]: dtype('O')
Следовательно, вы не можете спросить, какие строки относятся к типу - все они будут одного типа. Что вы можете сделать, это попытаться преобразовать записи в числа и проверить, где не удалось выполнить преобразование (это то, что делает код выше).
Как правило, плохая идея использовать серию для хранения смешанных числовых и нечисловых типов. Это приведет к тому, что ваша серия будет иметь object
dtype, который представляет собой не что иное, как последовательность указателей. Как и list
и, действительно, многие операции над такими сериями могут быть более эффективно обработаны list
.
С помощью этого отказа от ответственности вы можете использовать булевое индексирование через понимание списка:
res = df[[isinstance(value, str) for value in df['A']]]
print(res)
A B
2 Three 3
Эквивалент возможен с pd.Series.apply
, но это не более чем тонко завуалированный цикл и может быть медленнее, чем понимание списка:
res = df[df['A'].apply(lambda x: isinstance(x, str))]
Если вы уверены, что все нечисловые значения должны быть строками, вы можете преобразовать их в числовые и искать нули, то есть значения, которые не могут быть преобразованы:
res = df[pd.to_numeric(df['A'], errors='coerce').isnull()]