Python: данные строки фильтра Pandas на основе длины строки

Мне нравится отфильтровывать данные, длина строки которых не равна 10.

Если я пытаюсь отфильтровать строку, длина строки столбца A или B которой не равна 10, я попытался это сделать.

df=pd.read_csv('filex.csv')
df.A=df.A.apply(lambda x: x if len(x)== 10 else np.nan)
df.B=df.B.apply(lambda x: x if len(x)== 10 else np.nan)
df=df.dropna(subset=['A','B'], how='any')

Это работает медленно, но работает.

Однако иногда это приводит к ошибке, когда данные в представляют собой не строку, а число (интерпретируется как число, когда read_csv читает входной файл).

  File "<stdin>", line 1, in <lambda>
TypeError: object of type 'float' has no len()

Я считаю, что вместо этого должен быть более эффективный и элегантный код.


Основываясь на ответах и комментариях ниже, самое простое решение, которое я нашел:

df=df[df.A.apply(lambda x: len(str(x))==10]
df=df[df.B.apply(lambda x: len(str(x))==10]

или же

df=df[(df.A.apply(lambda x: len(str(x))==10) & (df.B.apply(lambda x: len(str(x))==10)]

или же

df=df[(df.A.astype(str).str.len()==10) & (df.B.astype(str).str.len()==10)]

Ответы

Ответ 1

import pandas as pd

df = pd.read_csv('filex.csv')
df['A'] = df['A'].astype('str')
df['B'] = df['B'].astype('str')
mask = (df['A'].str.len() == 10) & (df['B'].str.len() == 10)
df = df.loc[mask]
print(df)

Применяется к filex.csv:

A,B
123,abc
1234,abcd
1234567890,abcdefghij

вышеприведенный код

            A           B
2  1234567890  abcdefghij

Ответ 2

Более Pythonic способ фильтрации строк на основе заданных условий других столбцов и их значений:

Предполагая, что df:

data={"names":["Alice","Zac","Anna","O"],"cars":["Civic","BMW","Mitsubishi","Benz"],
     "age":["1","4","2","0"]}

df=pd.DataFrame(data)
df:
  age        cars  names
0   1       Civic  Alice
1   4         BMW    Zac
2   2  Mitsubishi   Anna
3   0        Benz      O

Затем:

df[
df['names'].apply(lambda x: len(x)>1) &
df['cars'].apply(lambda x: "i" in x) &
df['age'].apply(lambda x: int(x)<2)
  ]

Мы будем иметь:

  age   cars  names
0   1  Civic  Alice

В приведенных выше условиях мы смотрим сначала на длину строк, затем проверяем, существует ли буква ("i") в строках или нет, наконец, мы проверяем значение целых чисел в первом столбце.

Ответ 3

Если у вас есть числа в строках, они будут конвертироваться как float.

Преобразуйте все строки в строки после импорта из cvs. Для лучшей производительности разбивайте, что lambdas на несколько потоков.

Ответ 4

Вы можете использовать df.apply(len). это даст вам результат