Python: Pandas filtern Zeichenfolgendaten basierend auf ihrer Zeichenfolgenlänge


72

Ich filtere gerne Daten heraus, deren Stringlänge ungleich 10 ist.

Wenn ich versuche, eine Zeile herauszufiltern, deren Zeichenfolgenlänge in Spalte A oder B nicht gleich 10 ist, habe ich dies versucht.

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

Dies funktioniert langsam, funktioniert aber.

Es kann jedoch manchmal zu Fehlern kommen, wenn die Daten in A keine Zeichenfolge, sondern eine Zahl sind (interpretiert als Zahl, wenn read_csv die Eingabedatei liest).

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

Ich glaube, stattdessen sollte es effizienteren und eleganteren Code geben.


Basierend auf den Antworten und Kommentaren unten sind die einfachsten Lösungen, die ich gefunden habe:

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

oder

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

oder

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

Antworten:


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

Auf filex.csv angewendet:

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

Der obige Code wird gedruckt

            A           B
2  1234567890  abcdefghij

20

Eine pythonischere Methode zum Herausfiltern von Zeilen basierend auf den gegebenen Bedingungen anderer Spalten und ihren Werten:

Angenommen, ein df von:

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

Dann:

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

Wir werden haben :

  age   cars  names
0   1  Civic  Alice

Unter den obigen Bedingungen betrachten wir zuerst die Länge der Zeichenfolgen, dann prüfen wir, ob ein Buchstabe ("i") in den Zeichenfolgen vorhanden ist oder nicht, und schließlich überprüfen wir den Wert der ganzen Zahlen in der ersten Spalte.


6

Ich persönlich fand diesen Weg am einfachsten:

df['column_name'] = df[df['column_name'].str.len()!=10]

Dies scheint zunächst bequemer zu sein, ist jedoch langsamer als die Verwendung von apply, insbesondere bei größeren Datenmengen.
Smittie

1

Wenn Sie Zahlen in Zeilen haben, werden diese als Gleitkommazahlen konvertiert.

Konvertieren Sie alle Zeilen nach dem Import aus Lebensläufen in Zeichenfolgen. Teilen Sie diese Lambdas für eine bessere Leistung in mehrere Threads auf.



0

Filtere andere Werte als die Länge von 10 aus Spalte A und B heraus. Hier übergebe ich den Lambda-Ausdruck an die Funktion map (). Die Funktion map () gilt immer für Serienobjekte.

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

1
Dies wäre eine bessere Antwort, wenn Sie erklären würden, wie der von Ihnen bereitgestellte Code die Frage beantwortet.
pppery
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.