Python / Pandas将字符串解包为多个字段

时间:2018-04-12 14:14:38

标签: python string pandas csv dataframe

测量了相同物体的几个时间序列。不幸的是,x和y坐标都被组合成两个以逗号分隔的字符串。为了使事情变得更复杂,时间序列的数量和x坐标在时间序列之间变化。

因此,例如,我有一个类似于:

的数据框
Object   Overall_Prop   X                                              Y
obj1         4.5        "0, 1, 3, 6, 1, 3, 5, 7, 0, 1, 3, 5, 7"   "3, 9, 10, 11, 8, 10, 12, 14, 3.1, 8.5, 9, 12.5, 14.5"
obj2         9.9        "1, 3, 6, 9"                               "7, 9, 10, 14.2"

我想要的是一个看起来像这样的数据框:

Object    Overall_Prop  Curve  X  Y
obj1            4.5        1   0  3
obj1            4.5        1   1  9
obj1            4.5        1   3  10
obj1            4.5        1   6  11
obj1            4.5        2   1  8
obj1            4.5        2   3  10
obj1            4.5        2   5  12
obj1            4.5        2   7  14
obj1            4.5        3   0  3.1
obj1            4.5        3   1  8.5
obj1            4.5        3   3  9
obj1            4.5        3   5  12.5
obj1            4.5        3   7  14.5
obj2            9.9        1   1  7
obj2            9.9        1   3  9
obj2            9.9        1   6  10
obj2            9.9        1   9  14.2

顺便说一下,这个问题与pandas: how do I split a text in a column into multiple rows不同,因为这里我们有两列,结果字段必须适当配对。

因此额外的复杂化。

1 个答案:

答案 0 :(得分:2)

这是一种方法。我没有列出Curve列,因为不清楚这是如何定义的。

import pandas as pd
from itertools import chain

df = pd.DataFrame({'Object': ['obj1', 'obj2'],
                   'Overall_Prop': [4.5, 9.9],
                   'X': ['0, 1, 3, 6, 1, 3, 5, 7, 0, 1, 3, 5, 7', '1, 3, 6, 9'],
                   'Y': ['3, 9, 10, 11, 8, 10, 12, 14, 3.1, 8.5, 9, 12.5, 14.5', '7, 9, 10, 14.2']})

df['X'] = [list(map(float, x)) for x in df['X'].str.split(', ')]
df['Y'] = [list(map(float, x)) for x in df['Y'].str.split(', ')]

lens = list(map(len, df['X']))

res = pd.DataFrame({'Object': np.repeat(df['Object'], lens),
                    'Overall_Prop': np.repeat(df['Overall_Prop'], lens),
                    'X': list(chain.from_iterable(df['X'])),
                    'Y': list(chain.from_iterable(df['Y']))}).reset_index(drop=True)

print(res)

#    Object  Overall_Prop    X     Y
# 0    obj1           4.5  0.0   3.0
# 1    obj1           4.5  1.0   9.0
# 2    obj1           4.5  3.0  10.0
# 3    obj1           4.5  6.0  11.0
# 4    obj1           4.5  1.0   8.0
# 5    obj1           4.5  3.0  10.0
# 6    obj1           4.5  5.0  12.0
# 7    obj1           4.5  7.0  14.0
# 8    obj1           4.5  0.0   3.1
# 9    obj1           4.5  1.0   8.5
# 10   obj1           4.5  3.0   9.0
# 11   obj1           4.5  5.0  12.5
# 12   obj1           4.5  7.0  14.5
# 13   obj2           9.9  1.0   7.0
# 14   obj2           9.9  3.0   9.0
# 15   obj2           9.9  6.0  10.0
# 16   obj2           9.9  9.0  14.2