Python 如何将值列表写入一个";单元格“;在csv文件中?
我有一个循环,为每次迭代生成一个值列表。我希望将该值列表保存为csv“单元格”中的单个字符串。具体而言,我所拥有的是:Python 如何将值列表写入一个";单元格“;在csv文件中?,python,pandas,csv,Python,Pandas,Csv,我有一个循环,为每次迭代生成一个值列表。我希望将该值列表保存为csv“单元格”中的单个字符串。具体而言,我所拥有的是: index,username,user_id,data 1,name1,1,[string1,string2,string3,string4,...] 2,name2,2,[string5,string6,string7,string8,...] ... 资料 get_data返回字符串列表。与以逗号分隔的方式将这些字符串写入csv文件不同,我希望以嵌套方式将它们写入csv文
index,username,user_id,data
1,name1,1,[string1,string2,string3,string4,...]
2,name2,2,[string5,string6,string7,string8,...]
...
资料
get_data
返回字符串列表。与以逗号分隔的方式将这些字符串写入csv文件不同,我希望以嵌套方式将它们写入csv文件。如下所示:
index,username,user_id,data
1,name1,1,[string1,string2,string3,string4,...]
2,name2,2,[string5,string6,string7,string8,...]
...
更新:
我希望将结果存储在此表单中的原因之一是,我计划为每个用户保存更多数据。此数据的长度可能与my
get_data
调用的输出长度不同。解决问题的两个关键概念:
.to_csv()
在自动报价方面非常聪明。即使数据包含文字引号或逗号,在不更改默认分隔符的情况下读取/写入csv文件也不会有问题
ast.literal\u eval()
可以将列表的字符串表示形式转换回列表警告:此度量可能容易受到脏数据的攻击。确保在保存csv文件之前执行数据清理。
import pandas as pd
import ast # for literal string parsing
# data
df = pd.DataFrame(
data={
"index": range(1,5),
"username": [f"name{i}" for i in range(4)],
"user_id": range(1,5),
# initialize each data cell with an empty list
"data": [list() for _ in range(4)]
}
)
# use `.at[]` to append some values
df.at[0, "data"] += [1, 2, 3]
df.at[2, "data"] += [4]
# mixed types, quotes and commas
df.at[3, "data"] += [1, '"', -3.3, "'", ",,,", ";"]
print(df)
# save
file_path = "/mnt/ramdisk/out.csv"
df.to_csv(file_path)
# load
df_read = pd.read_csv(file_path, index_col=0)
# parse, because contents in data cells were loaded as strings
for i in range(len(df_read)):
s = df_read.iat[i, 3]
print(f"row {i} before: {type(s)}")
df_read.iat[i, 3] = ast.literal_eval(s)
print(f" after: {type(s)}, len={len(s)}")
print(df_read) # identical to df
# check elements within list
ls = df_read.iat[3,3]
for i in range(len(ls)):
print(f"row {i}: {type(ls[i])}, contents={ls[i]}")
结果
(0)原始数据帧(未打印引用,但不影响数据本身)
(1) 原始csv文件
bill@bill-laptop-deb: /mnt/ramdisk
$ cat out.csv
,index,username,user_id,data
0,1,name0,1,"[1, 2, 3]"
1,2,name1,2,[]
2,3,name2,3,[4]
3,4,name3,4,"[1, '""', -3.3, ""'"", ',,,', ';']"
(2) 用python重新加载文件
df_read # identical to input
Out[8]:
index username user_id data
0 1 name0 1 [1, 2, 3]
1 2 name1 2 []
2 3 name2 3 [4]
3 4 name3 4 [1, ", -3.3, ', ,,,, ;]
(3) LibreOffice 6也正确导入csv文件
(4) 对加载的数据进行类型检查
ls = df_read.iat[3,3] # a mixed-up list
for i in range(len(ls)):
print(f"row {i}: {type(ls[i])}, contents={ls[i]}")
row 0: <class 'int'>, contents=1
row 1: <class 'str'>, contents="
row 2: <class 'float'>, contents=-3.3
row 3: <class 'str'>, contents='
row 4: <class 'str'>, contents=,,,
row 5: <class 'str'>, contents=;
ls=df_read.iat[3,3]#一个混合列表
对于范围内的i(len(ls)):
打印(f“行{i}:{type(ls[i])},内容={ls[i]}”)
第0行:,内容=1
第1行:,内容=“
第2行:,内容=-3.3
第3行:,内容=
第4行:,内容=,,,
第5行:,内容=;
可以看出,尽管引用/转义使文件很难被人阅读,但对熊猫和图书馆办公室来说,这应该不是问题
旁注:出于可追溯性和数据完整性的考虑,强烈建议使用数据库。这种连续的数据扩充场景正是数据库系统设计的目的。如果您的项目独立运行,SQLite应该是一个轻量级的选择,在部署方面相对容易。这一问题的两个关键概念ms:
.to_csv()
在自动引用方面非常聪明。在不更改默认分隔符的情况下读取/写入csv文件应该没有问题,即使数据包含文字引号或逗号
ast.literal_eval()
可以将列表的字符串表示形式转换回列表。警告:此度量可能容易受到脏数据的攻击。请确保在保存csv文件之前执行数据清理。
import pandas as pd
import ast # for literal string parsing
# data
df = pd.DataFrame(
data={
"index": range(1,5),
"username": [f"name{i}" for i in range(4)],
"user_id": range(1,5),
# initialize each data cell with an empty list
"data": [list() for _ in range(4)]
}
)
# use `.at[]` to append some values
df.at[0, "data"] += [1, 2, 3]
df.at[2, "data"] += [4]
# mixed types, quotes and commas
df.at[3, "data"] += [1, '"', -3.3, "'", ",,,", ";"]
print(df)
# save
file_path = "/mnt/ramdisk/out.csv"
df.to_csv(file_path)
# load
df_read = pd.read_csv(file_path, index_col=0)
# parse, because contents in data cells were loaded as strings
for i in range(len(df_read)):
s = df_read.iat[i, 3]
print(f"row {i} before: {type(s)}")
df_read.iat[i, 3] = ast.literal_eval(s)
print(f" after: {type(s)}, len={len(s)}")
print(df_read) # identical to df
# check elements within list
ls = df_read.iat[3,3]
for i in range(len(ls)):
print(f"row {i}: {type(ls[i])}, contents={ls[i]}")
结果
(0)原始数据帧(未打印引用,但不影响数据本身)
(1) 原始csv文件
bill@bill-laptop-deb: /mnt/ramdisk
$ cat out.csv
,index,username,user_id,data
0,1,name0,1,"[1, 2, 3]"
1,2,name1,2,[]
2,3,name2,3,[4]
3,4,name3,4,"[1, '""', -3.3, ""'"", ',,,', ';']"
(2) 用python重新加载文件
df_read # identical to input
Out[8]:
index username user_id data
0 1 name0 1 [1, 2, 3]
1 2 name1 2 []
2 3 name2 3 [4]
3 4 name3 4 [1, ", -3.3, ', ,,,, ;]
(3) LibreOffice 6也正确导入csv文件
(4) 对加载的数据进行类型检查
ls = df_read.iat[3,3] # a mixed-up list
for i in range(len(ls)):
print(f"row {i}: {type(ls[i])}, contents={ls[i]}")
row 0: <class 'int'>, contents=1
row 1: <class 'str'>, contents="
row 2: <class 'float'>, contents=-3.3
row 3: <class 'str'>, contents='
row 4: <class 'str'>, contents=,,,
row 5: <class 'str'>, contents=;
ls=df_read.iat[3,3]#一个混合列表
对于范围内的i(len(ls)):
打印(f“行{i}:{type(ls[i])},内容={ls[i]}”)
第0行:,内容=1
第1行:,内容=“
第2行:,内容=-3.3
第3行:,内容=
第4行:,内容=,,,
第5行:,内容=;
可以看出,尽管引用/转义使文件很难被人阅读,但对熊猫和图书馆办公室来说,这应该不是问题
旁注:为了可追溯性和数据完整性,强烈建议使用数据库。这种连续的数据扩充场景正是数据库系统设计的目的。如果您的项目独立运行,SQLite应该是一个轻量级的选择,在部署方面相对容易。IMHO,这将是一个非常糟糕的存储
csv
的方法,因为它破坏了您的csv结构。我必须承认,我也不是特别喜欢它。但是,如果不使用不同的文件类型或数据库,您将如何存储它呢?每个用户有多行,每个行对应get_data
响应中的一个字符串。或者只对值使用不同的分隔符,即代码>为每个用户使用多行将使添加不同长度的数据变得困难或混乱。代码中包含了什么内容;分隔符看起来像?嗯,这将是一个非常糟糕的方式来存储csv
,因为它破坏了您的csv结构。我必须承认,我也不是特别喜欢它。但是,如果不使用不同的文件类型或数据库,您将如何存储它呢?每个用户有多行,每个行对应get_data
响应中的一个字符串。或者只对值使用不同的分隔符,即代码>为每个用户使用多行将使添加不同长度的数据变得困难或混乱。代码中包含了什么内容;分隔符看起来像什么?再次警告:不要为了生产目的而这样做。这并没有针对所有类型的脏数据进行广泛的测试。只需将它们存储在数据库中。再次警告:不要出于生产目的而这样做。这并没有针对所有类型的脏数据进行广泛的测试。只需将它们存储在数据库中。