Reconstruire les pandas Dataframe
Im assez nouveau sur Python. J'ai du mal à reconstruire un mauvais Dataframe. Mon Dataframe ressemble à ceci:
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']})
Comme vous pouvez le voir, j'ai les "id´s" dans le premier, deuxième et troisième col. Idem pour les autres Valeurs.
Mon objectif est d'avoir un Dataframe dans lequel chaque Col n'a que les Valeurs commençant par la même sous-chaîne comme cet exemple:
J'ai déjà essayé d'utiliser des boucles for et if Statments pour vérifier si une certaine sous-chaîne est dans ma chaîne. si c'est vrai, je crée une nouvelle colonne et j'écris ma valeur à l'intérieur
for x in df['col1']:
if 'id' in x:
df['newCol']=x
Je sais que ce code ne résoudra jamais mon problème, peut-être qu'il existe une fonction pandas qui peut m'aider à résoudre ce problème
Si quelque chose n'est pas clair, demandez-moi simplement que je ferai de mon mieux pour expliquer mon problème. Merci d'avance pour votre aide et allez-y doucement :)
Réponses
Vous pouvez utiliser sorted()avec la fonction de touche personnalisée:
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)
Impressions:
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
Une autre version, d'après les commentaires:
df = pd.DataFrame([sorted(l, key=key_fn) for l in df.values], columns=df.columns)
print(df)
Si possible, simplifiez la solution en fractionnant les valeurs par le premier vide:
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
Sinon, vous pouvez utiliser 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
Essaye ça:
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
Vous pouvez d'abord fondre le dataframe, puis utiliser numpy select pour réorganiser les noms, et enfin pivoter :
(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