web-dev-qa-db-fra.com

Fractionner des chaînes de tuples en colonnes, en pandas

J'ai la suivante DataFrame, où Track ID est l'index de la ligne. Comment diviser la chaîne de la colonne stats en 5 colonnes de nombres?

Track ID    stats
14.0    (-0.00924175824176, 0.41, -0.742016492568, 0.0036830094242, 0.00251748449963)
28.0    (0.0411538461538, 0.318230769231, 0.758717081514, 0.00264000622468, 0.0106535783677)
42.0    (-0.0144351648352, 0.168438461538, -0.80870348637, 0.000816872566404, 0.00316572586742)
56.0    (0.0343461538462, 0.288730769231, 0.950844962874, 6.1608706775e-07, 0.00337262030771)
70.0    (0.00905164835165, 0.151030769231, 0.670257006716, 0.0121790506745, 0.00302182567957)
84.0    (-0.0047967032967, 0.171615384615, -0.552879463981, 0.0500316517755, 0.00217970256969)
28
t_n

Et pour l’autre cas, en supposant que ce soient des chaînes qui ressemblent à des n-uplets:

In [74]: df['stats'].str[1:-1].str.split(',', expand=True).astype(float)
Out[74]:
          0         1         2         3         4
0 -0.009242  0.410000 -0.742016  0.003683  0.002517
1  0.041154  0.318231  0.758717  0.002640  0.010654
2 -0.014435  0.168438 -0.808703  0.000817  0.003166
3  0.034346  0.288731  0.950845  0.000001  0.003373
4  0.009052  0.151031  0.670257  0.012179  0.003022
5 -0.004797  0.171615 -0.552879  0.050032  0.002180

(remarque: pour les anciennes versions de pandas (<0.16.1), vous devez utiliser return_type='frame' au lieu du mot-clé expand)

À propos, s'il s'agit de tuples et non de chaînes, vous pouvez simplement procéder comme suit:

pd.DataFrame(df['stats'].tolist(), index=df.index)
51
joris

Si vous avez une séquence de tuples et non des chaînes et que vous les voulez sous forme de colonnes DataFrame, voici l'approche la plus simple:

df = pd.concat([df['Track ID'],pd.DataFrame(df['stats'].values.tolist())], axis=1)

S'il s'agit en fait de chaînes, vous pouvez d'abord le convertir en listes, appliquez ensuite l'opération ci-dessus:

dfpart = pd.DataFrame(df['stats'].apply(lambda x: x.strip('()').split(', ')).values.tolist()).astype(float)
df = pd.concat([df['Track ID'], dfpart], axis=1)
2
TheBlackCat

En supposant que vous ayez une colonne contenant des n-uplets (comme il apparaît dans votre exemple) plutôt que des chaînes, cela fonctionnera:

df = pandas.DataFrame({'Track ID': [14, 28, 42], 'stats': [(1, 2, 3, 4, 5), (1, 2, 3, 4, 5), (1, 2, 3, 4, 5)]}).set_index("Track ID")

from operator import itemgetter
for i in range(5):
    df["Col {}".format(i)] = df.stats.apply(itemgetter(i))

Si vous avez des chaînes qui ressemblent à des n-uplets, vous pouvez d'abord les analyser, puis appliquer le même motif que ci-dessus:

df = df2 = pandas.DataFrame({'Track ID': [14, 28, 42], 'stats': ["(1, 2, 3, 4, 5)", "(1, 2, 3, 4, 5)", "(1, 2, 3, 4, 5)"]}).set_index("Track ID")
df.stats = df2.stats.str.strip("()").str.split(", ")
0
chthonicdaemon