【问题标题】:Python/Pandas Unpacking of Field String into Multiple Fields [duplicate]Python / Pandas将字段字符串解包为多个字段[重复]
【发布时间】:2018-09-22 17:52:17
【问题描述】:

对相同的对象测量了几个时间序列。不幸的是,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 不同,因为这里我们有两列,结果字段必须适当配对。

因此增加了复杂性。

【问题讨论】:

  • 坦率地说,我不知道如何开始。我想我可以尝试使用 for 循环,但我有一种感觉,如果我能以某种方式创建多索引,我就可以从宽格式变为长格式。但是话又说回来,时间序列的数量是可变的,所以我不知道如何在不使用 for 循环以某种方式处理字符串的情况下做到这一点。
  • 这是一个类似的帖子:stackoverflow.com/questions/17116814/…

标签: python string pandas csv dataframe


【解决方案1】:

这是一种方法。我没有包含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

【讨论】:

  • 谢谢@jpp,这看起来很不错。接下来我将尝试它,但在我想澄清“曲线”的含义之前。随着 X 值从较高值变为较低值的超时,开始一条新曲线。因此,在您的打印输出中,当 X 从 6.0 下降到 1.0 时,obj1 的曲线编号 2 开始。顺便说一句,这个解决方案似乎与“pandas: How do I split text in a column into multiple columns”中建议的解决方案有很大不同并且适用性更广。
  • @JDS。是的,解决方案不同。这个效率更高,另一个更面向 pandas。你喜欢哪个是你的选择。回复:曲线,如果您不能自己添加此列(在先决条件研究之后),我建议您作为一个单独的问题提出。
猜你喜欢
  • 1970-01-01
  • 2012-03-31
  • 1970-01-01
  • 2012-09-11
  • 1970-01-01
  • 2019-12-15
  • 1970-01-01
  • 2018-08-16
  • 2019-03-24
相关资源
最近更新 更多