【问题标题】:Operate on a column of strings of lists对一列列表字符串进行操作
【发布时间】:2019-09-08 03:33:54
【问题描述】:

我正在处理 python 上的 pandas 项目。我收到这样的 .csv 文件作为输入:

姓名、时间、数据 A,5.6,"[1,2,3]" A,1.2,"[1.4,3,8.9]" ... B,3.4,"[0.2,3,5.1]" 抄送..

(我有每个名字的数千个数据,比如 10 个名字)。 所以在 pandas 中,表格是:

名称时间数据 5.6 [1,2,3] 1.2 [1.4,3,8.9] ... B 3.4 [0.2,3,5.1] ...

我需要将“数据”列中列表的所有数字转换为另一个度量单位(所以基本上,将列表的每个数字乘以一个标量)。 我遇到了问题,因为在我收到的 csv 中,数据被保存为字符串。所以首先我必须将字符串转换为浮点数列表,然后将列表中的 3 个数字乘以标量(例如 2),然后再次将列表转换为字符串。

我知道对整列执行操作就像:

df['Data'] = df['Data'].apply(lambda x: x*2)

我可以用这种方式将列表“a”的每个数字相乘:

[x*2 for x in a]

我可以将字符串转换为带有 ast 的列表:

a = ast.literal_eval(a) # (and with a = str(a).strip('[]') i can return to the string)

但我不能把这三件事结合起来。

你有什么解决办法吗? (不一定使用我在这里尝试的相同方法)。 提前谢谢!

【问题讨论】:

  • 只需将您的 3 个命令加入到 applylambda 中,如下所示 df.Data.apply(lambda x: str([y*2 for y in ast.literal_eval(x)]))。您要将列表转换回字符串的最后一步似乎很奇怪。

标签: python pandas csv


【解决方案1】:

我建议首先使用 ast.literal_eval 将所有内容转换为列表:

import pandas as pd

df = pd.DataFrame({
    'Name': ['A', 'A'],
    'Time': [5.6, 1.2],
    'Data': ["[1, 2, 3]", "[1.4, 3, 8.9]"]
})

import ast

df['Data'] = df['Data'].apply(ast.literal_eval)

然后你就可以使用常规的列表操作了:

df['Data'] = df['Data'].apply(lambda x: [i*2 for i in x])
print(df['Data'])

输出:

0         [2, 4, 6]
1    [2.8, 6, 17.8]
Name: Data, dtype: object

编辑:

要将系列转换回字符串,只需再次使用apply

df['Data'] = df['Data'].apply(str)

不过,我真的不建议这样做 - 将列表存储为列表而不是字符串表示形式更方便。如果您想继续使用列表操作,最好将其保留为列表。

【讨论】:

  • 1.在此解决方案中,python 不会将列表转换回字符串。尽管使用df['Data'] = df['Data'].apply(str),你可以很容易地做到这一点,虽然我不知道你为什么会 - 你所做的所有操作都会在列表上更方便
  • 2. pandas 实际上有一个 pd.resample 函数,你应该研究一下 - pandas.pydata.org/pandas-docs/stable/reference/api/…
  • @Elia resample 超出了这个问题的范围。您必须将 rangeindex 转换为 datetimeindex。见:stackoverflow.com/questions/30857680/…
  • 字符串中的“nan”表示未填充的值 - 您不应在空列上进行乘法运算。您可以尝试将其设置为零吗?
  • @Kraton 最好使用 None 然后单独处理逻辑:df['Data'] = df['Data'].str.replace("nan", "None"); df['Data'] = df['Data'].apply(lambda x: [i*2 if i is not None else None for i in x]))
【解决方案2】:

您不需要利用ast - 您可以从[] "“清理”您的列表文本表示并使用split(",") 来获取字符串列表。

使用 map 转换为浮点数并乘以您的常量:

创建演示数据文件:

data = """Name,Time,Data
A,5.6,"[1,2,3]"
A,1.2,"[1.4,3,8.9]"
B,3.4,"[0.2,3,5.1]" """

with open("d.txt","w") as f:
    f.write(data)

流程演示数据文件:

import pandas as pd

df = pd.read_csv("d.txt")
print(df)

constant = 3
df['Data_2'] = df['Data'].apply(
    lambda x: [x*constant for x in map(float, x.strip("[]\" ").split(","))])


print(df)

输出:

  Name  Time          Data
0    A   5.6       [1,2,3]
1    A   1.2   [1.4,3,8.9]
2    B   3.4  [0.2,3,5.1] 

转换后的输出:

  Name  Time          Data                                         Data_2
0    A   5.6       [1,2,3]                                [3.0, 6.0, 9.0]
1    A   1.2   [1.4,3,8.9]   [4.199999999999999, 9.0, 26.700000000000003]
2    B   3.4  [0.2,3,5.1]   [0.6000000000000001, 9.0, 15.299999999999999]

【讨论】:

    猜你喜欢
    • 2021-06-27
    • 2013-10-23
    • 1970-01-01
    • 2016-10-27
    • 1970-01-01
    • 1970-01-01
    • 2011-11-21
    • 2017-06-30
    • 1970-01-01
    相关资源
    最近更新 更多