在一列列表字符串上操作

时间:2019-09-07 18:32:00

标签: python pandas csv

我正在使用python在pandas中开发一个项目。我收到这样的.csv文件作为输入:

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]"
ecc..

(每个名字我都有成千上万的数据,比如10个名字)。 因此,在熊猫中,表为:

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]
...

我需要将“数据”(Data)列中列表的所有数字转换为另一个度量单位(因此,基本上,列表中的每个数字都用标量来表示)。 我遇到了问题,因为在接收到的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)

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

您有什么解决方案吗? (不一定使用我在这里尝试过的相同方法)。 预先谢谢你!

2 个答案:

答案 0 :(得分:4)

我建议先使用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 :(得分:2)

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

使用map转换为float并乘以您的常数:

创建演示数据文件:

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]