pandas - 将字符串转换为字符串列表[重复]
Posted
技术标签:
【中文标题】pandas - 将字符串转换为字符串列表[重复]【英文标题】:pandas - convert string into list of strings [duplicate] 【发布时间】:2018-01-27 06:11:42 【问题描述】:我有这个“file.csv”文件可以用 pandas 读取:
Title|Tags
T1|"[Tag1,Tag2]"
T1|"[Tag1,Tag2,Tag3]"
T2|"[Tag3,Tag1]"
使用
df = pd.read_csv('file.csv', sep='|')
输出是:
Title Tags
0 T1 [Tag1,Tag2]
1 T1 [Tag1,Tag2,Tag3]
2 T2 [Tag3,Tag1]
我知道Tags
列是一个完整的字符串,因为:
In [64]: df['Tags'][0][0]
Out[64]: '['
我需要将其读取为字符串列表,例如["Tag1","Tag2"]
。我尝试了this 问题中提供的解决方案,但没有运气,因为我的[
和]
字符实际上把事情搞砸了。
预期的输出应该是:
In [64]: df['Tags'][0][0]
Out[64]: 'Tag1'
【问题讨论】:
我之前问过一个类似的问题,你可以在这里看到答案:***.com/questions/44529483/… 【参考方案1】:您可以手动拆分字符串:
>>> df['Tags'] = df.Tags.apply(lambda x: x[1:-1].split(','))
>>> df.Tags[0]
['Tag1', 'Tag2']
【讨论】:
或者在加载时应用...df = pd.read_csv('file.csv', sep='|', converters='Tags': lambda x: x[1:-1].split(','))
@JonClements, converters='Tags': lambda x: x[1:-1].split(',')
让我省了很多麻烦。谢谢你。【参考方案2】:
或者
df.Tags=df.Tags.str[1:-1].str.split(',').tolist()
【讨论】:
@WeNToBen - 不错的解决方案。想扩大一点吗?为什么我们需要str[1:-1]
,为什么不需要str[0:-1]
? (顺便说一句,对我来说,两者都产生相同的结果)。另外,如果split()
已经创建了一个列表,为什么还要显式调用tolist()
?
@zerohedge 因为你想删除开头的“[”和结尾的“]”
谢谢。为什么tolist()
在split()
之后(它本身会创建一个列表,不是吗?)
@zerohedge 啊,我需要删除的那个,你说得对【参考方案3】:
我认为你可以使用 json 模块。
import json
import pandas
df = pd.read_csv('file.csv', sep='|')
df['Tags'] = df['Tags'].apply(lambda x: json.loads(x))
所以这将像以前一样加载您的数据框,然后将 lambda 函数应用于Tags
列中的每个项目。 lambda 函数调用 json.loads()
将列表的字符串表示形式转换为实际列表。
【讨论】:
我认为这是一个更好的解决方案,更不容易出错!另外请注意,您可以将json.loads
直接作为apply
参数传递:df['Tags'].apply(json.loads)
【参考方案4】:
您可以使用strip
和split
将字符串转换为列表。
df_out = df.assign(Tags=df.Tags.str.strip('[]').str.split(','))
df_out.Tags[0][0]
输出:
'Tag1'
【讨论】:
【参考方案5】:您可以使用内置的ast.literal_eval
,它适用于元组和列表
import ast
import pandas as pd
df = pd.DataFrame("mytuples": ["(1,2,3)"])
print(df.iloc[0,0])
# >> '(1,2,3)'
df["mytuples"] = df["mytuples"].apply(ast.literal_eval)
print(df.iloc[0,0])
# >> (1,2,3)
编辑:eval
应该避免!如果正在评估的字符串是os.system(‘rm -rf /’)
,它将开始删除您计算机上的所有文件(here)。对于ast.literal_eval
,提供的字符串或节点只能包含以下 Python 文字结构:字符串、字节、数字、元组、列表、字典、集合、布尔值和无 (here)。谢谢@TrentonMcKinney :)
【讨论】:
【参考方案6】:您的df['Tags']
似乎是一个字符串列表。如果您打印该列表,您应该得到 ["[tag1,tag2]","[Tag1,Tag2,Tag3]","[Tag3,Tag1]"]
这就是为什么当您调用第一个元素的第一个元素时,您实际上得到的是字符串的第一个单个字符,而不是您想要的。
您要么需要在之后解析该字符串。执行类似的操作
df['Tags'][0] = df['Tags'][0].split(',')
但是正如您在引用的示例中看到的那样,这会给您一个看起来像
的列表in: df['Tags'][0][0]
out: '[tag1'`
您需要的是一种解析字符串并编辑出多个字符的方法。您可以使用简单的正则表达式来执行此操作。比如:
import re
df['Tags'][0] = re.findall(r"[\w']+", df['Tags'][0])
print(df['Tags'][0][0])
将打印:
'tag1'
使用涉及 Pandas 转换器的其他答案,您可以编写如下转换器:
def clean(seq_string):
return re.findall(r"[\w']+", seq_string)
如果您不了解正则表达式,它们可能非常强大,但如果您不确定输入字符串的内容,它们也会变得不可预测。此处使用的表达式r"[\w']+"
将匹配任何常见的单词字符字母数字和下划线,并将其他所有内容视为re.findall
拆分列表的点。
【讨论】:
【参考方案7】:这是一个简单而高效的操作:
df['Tags'].str.split(',')
【讨论】:
不去掉开头和结尾的方括号以上是关于pandas - 将字符串转换为字符串列表[重复]的主要内容,如果未能解决你的问题,请参考以下文章
将包含字符串和 NAN 的列转换为 Pandas 中的整数列表