Ich habe den folgenden Datenrahmen

      col1          col2
0     str9          val1
1     str8          val2
2     str4          val3
3     str2          val4
4  unknown1    asdvstr1df
5  random1  teststr2test

Und die folgende Liste

strings = ['str1', 'str2', 'str3', 'str4']

Ich möchte den Wert in Spalte 1 ersetzen, wenn an einer beliebigen Stelle in der Zeichenfolge in Spalte 2 eine Übereinstimmung mit der angegebenen Liste, Zeichenfolgen, vorliegt.

Hinweis: col2 kann die Werte der Liste 'string' in der Zeichenfolge oder an beiden Enden enthalten.

Derzeit mache ich dies mit einer hässlichen und langsamen verschachtelten Schleife:

import pandas as pd

data_file = pd.DataFrame(data = ([['str9', 'val1'], ['str8',  'val2'], ['str4','val3'] , ['str2', 'val4'] , ['unknown', 'asdvstr1df'] , ['unknown', 'teststr2test']] ), columns = (['col1', 'col2']), dtype = str)
strings = ['str1', 'str2', 'str3', 'str4']

for value in range(data_file.shape[0]):
    for text in strings:
        if (str(data_file.col2[value]).find(text) != -1):
            data_file.loc[value, 'col1'] = text

Ich bin mir nicht sicher, wie ich diesen langsamen Prozess verbessern kann. Wie kann ich dafür sorgen, dass dies schneller als die aktuelle O (nm) -Zeit ausgeführt wird (n ist die Größe der Datendatei, m die Größe der Liste, die als Zeichenfolgen bezeichnet wird)?

Die Ausgabe sollte sein:

   col1          col2
0  str9          val1
1  str8          val2
2  str4          val3
3  str2          val4
4  str1    asdvstr1df
5  str2  teststr2test
3
dward4 18 Apr. 2018 im 17:32

3 Antworten

Beste Antwort

IIUC,

x = '(' + '|'.join(strings)+ ')'
df.assign(col1 = df.col2.str.extract(x, expand=False).combine_first(df.col1))

Ausgabe:

   col1          col2
0  str9          val1
1  str8          val2
2  str4          val3
3  str2          val4
4  str1    asdvstr1df
5  str2  teststr2test
5
Scott Boston 18 Apr. 2018 im 14:45

Sie können replace zweimal mit regex verwenden

d1=dict(zip(strings,[1,2,3,4]))
d2=dict(zip([1,2,3,4],strings))

df.loc[df.col1=='unknown','col1']=df.col2.replace(d1,regex=True).replace(d2)
df
Out[970]: 
   col1          col2
0  str9          val1
1  str8          val2
2  str4          val3
3  str2          val4
4  str1    asdvstr1df
5  str2  teststr2test
3
YOBEN_S 18 Apr. 2018 im 14:44

Versuche dies:

data_file["col1"] = data_file["col2"].apply(lambda y:strings[[True if x in y 
else False for x in strings ].index(True)] if any([True if x in y else False 
for x in strings ]) else y)
print(data_file)

AUSGABE:

   col1          col2
0  val1          val1
1  val2          val2
2  val3          val3
3  val4          val4
4  str1    asdvstr1df
5  str2  teststr2test
1
FadeoN 18 Apr. 2018 im 14:41