Подтвердить что ты не робот

Разделить строки в кортежах на столбцы, в Pandas

У меня есть следующий DataFrame, где Track ID - индекс строки. Как разбить строку в столбце stats на 5 столбцов чисел?

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)
4b9b3361

Ответ 1

И для другого случая, если предположить, что это строки, похожие на кортежи:

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

(примечание: для более старых версий pandas (< 0.16.1) вам нужно использовать return_type='frame' вместо ключевого слова expand)

Кстати, если это кортежи, а не строки, вы можете просто сделать следующее:

df['stats'].apply(pd.Series)

Этот последний также можно комбинировать с приведенным выше (если return_type='frame' еще не доступен):

df['stats'].str[1:-1].str.split(',').apply(pd.Series).astype(float)

Ответ 2

Если у вас есть последовательность кортежей, а не строк, и вы хотите, чтобы они были столбцами DataFrame, это самый простой способ:

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

Если это фактически строки, вы можете сначала преобразовать их в списки так, а затем применить описанную выше операцию:

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

Ответ 3

Предполагая, что у вас есть столбец, который содержит кортежи (как показано в вашем примере), а не строки, это будет работать:

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

Если у вас на самом деле есть строки, похожие на кортежи, вы можете сначала их разобрать, а затем применить тот же шаблон, что и выше:

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(", ")