Pandas Dataframe neu erstellen
Ich bin ziemlich neu in Python. Ich habe Probleme mit der Rekonstruktion eines schlechten Datenrahmens. Mein Datenrahmen sieht folgendermaßen aus:
df = pd.DataFrame({'col1': ['id 1', 'id 2', 'test 3', 'test 4'],
'col2': ['test 1', 'test 2',
'Number 6135', 'id 4'],
'col3': ['Number 12344', 'Number 21612','id 3','Number 1131']})
Wie Sie sehen können, habe ich die "IDs" in der ersten, zweiten und Thrid-Spalte. Gleiches gilt für die anderen Werte.
Mein Ziel ist es, einen Datenrahmen zu haben, in dem jeder Col nur die Werte hat, die mit dem gleichen Teilstring wie in diesem Beispiel beginnen:
Ich habe bereits versucht, for-Schleifen und if-Anweisungen zu verwenden, um zu überprüfen, ob sich ein bestimmter Teilstring in meinem String befindet. Wenn das stimmt, erstelle ich eine neue Spalte und schreibe meinen Wert hinein
for x in df['col1']:
if 'id' in x:
df['newCol']=x
Ich weiß, dass dieser Code mein Problem niemals lösen wird. Vielleicht gibt es einige Pandas-Funktionen, die mir helfen können, dieses Problem zu lösen
Wenn etwas nicht klar ist, frag mich einfach, ich werde mein Bestes geben, um mein Problem zu erklären. Vielen Dank im Voraus für Ihre Hilfe und schonen Sie mich :)
Antworten
Sie können sorted()mit benutzerdefinierten Tastenfunktion verwenden:
def key_fn(x):
if 'id' in x:
return 0
if 'test' in x:
return 1
if 'Number' in x:
return 2
return 3
df = df.apply(lambda x: pd.Series(sorted(x, key=key_fn)), axis=1)
df = df.rename(columns=lambda x: 'col{}'.format(x+1))
print(df)
Drucke:
col1 col2 col3
0 id 1 test 1 Number 12344
1 id 2 test 2 Number 21612
2 id 3 test 3 Number 6135
3 id 4 test 4 Number 1131
Eine andere Version aus den Kommentaren:
df = pd.DataFrame([sorted(l, key=key_fn) for l in df.values], columns=df.columns)
print(df)
Wenn möglich, vereinfachen Sie die Lösung, indem Sie die Werte durch das erste Leerzeichen teilen:
df = (df.reset_index()
.melt('index')
.assign(new = lambda x: x['value'].str.split().str[0])
.pivot('index','new','value'))
print (df)
new Number id test
index
0 Number 12344 id 1 test 1
1 Number 21612 id 2 test 2
2 Number 6135 id 3 test 3
3 Number 1131 id 4 test 4
Sonst können Sie verwenden Series.str.extract:
L = ['id','test','Number']
df = (df.reset_index()
.melt('index')
.assign(new = lambda x: x['value'].str.extract(f'({"|".join(L)})', expand=False))
.pivot('index','new','value'))
print (df)
new Number id test
index
0 Number 12344 id 1 test 1
1 Number 21612 id 2 test 2
2 Number 6135 id 3 test 3
3 Number 1131 id 4 test 4
Versuche dies:
s = df.melt()['value']
df_final = pd.DataFrame({x: s[s.str.startswith(x)].values
for x in s.str.split().str[0].unique()})
Out[27]:
id test Number
0 id 1 test 3 Number 6135
1 id 2 test 4 Number 12344
2 id 4 test 1 Number 21612
3 id 3 test 2 Number 1131
Sie können zuerst den Datenrahmen schmelzen , dann mit numpy select die Namen neu anordnen und schließlich schwenken :
(df.melt(ignore_index=False)
.assign(variable=lambda x: np.select([x.value.str.startswith("id"),
x.value.str.startswith("test"),
x.value.str.startswith("Number")],
["col1", "col2", "col3"]))
.reset_index()
.pivot("index", "variable", "value")
.rename_axis(columns=None, index=None))
col1 col2 col3
0 id 1 test 1 Number 12344
1 id 2 test 2 Number 21612
2 id 3 test 3 Number 6135
3 id 4 test 4 Number 1131