Pandas DataFrame存储列表为字符串:如何转换回列表?

Gya*_*eda 41 python string list dataframe pandas

我有一个n- by- m的 Pandas DataFrame df定义如下.(我知道这不是最好的方法.对于我在实际代码中尝试做的事情是有意义的,但这个帖子的TMI就是这样,所以请理解我的方法,这种方法适用于我的特定场景.)

>>> df = DataFrame(columns=['col1'])
>>> df.append(Series([None]), ignore_index=True)
>>> df
Empty DataFrame
Columns: [col1]
Index: []
Run Code Online (Sandbox Code Playgroud)

我将列表存储在此DataFrame的单元格中,如下所示.

>>> df['column1'][0] = [1.23, 2.34]
>>> df
     col1
0  [1, 2]
Run Code Online (Sandbox Code Playgroud)

出于某种原因,DataFrame将此列表存储为字符串而不是列表.

>>> df['column1'][0]
'[1.23, 2.34]'
Run Code Online (Sandbox Code Playgroud)

我有两个问题要问你.

  1. 为什么DataFrame将列表存储为字符串,是否有解决此问题的方法?
  2. 如果没有,那么是否有一种Pythonic方法将此字符串转换为列表?

更新

我使用的DataFrame已经保存并从CSV格式加载.这种格式而不是DataFrame本身将列表从字符串转换为文字.

mar*_*xor 66

您可以直接使用熊猫 -
df = pd.read_csv(df_name, converters={'column_name': eval})

这将读取该列作为它在 python 中的相应 dtype 而不是字符串。

  • 我到处寻找,这就是我一直在寻找的东西。谢谢。 (7认同)
  • 这是正确的答案,因为它避免了导入另一个库。 (4认同)
  • 我遇到了同样的问题,这个答案解决了原因而不是症状,这就是我投票支持它的原因 (3认同)
  • 最好的解决方案,放手。 (3认同)
  • 只需确保您使用的是 pandas.eval 而不是内置 eval。如果您的 csv 文件中有正确的表达式,内置 eval 将很乐意删除您的所有文件。请参阅 https://realpython.com/python-eval-function/#minimizing-the-security-issues-of-eval。 (3认同)
  • @markroxor - 更新:`ast.literal_eval` 速度快了 15 倍,而且看起来 `pd.eval` 似乎可以回退到 Python eval。 (2认同)

Ale*_*ton 50

正如您所指出的,在将pandas DataFrames保存和加载为.csv文件格式时,通常会发生这种情况.

在您的情况下,这发生是因为列表对象具有字符串表示,允许它们存储为.csv文件.加载.csv遗嘱然后产生该字符串表示.

如果要存储实际对象,则应该使用DataFrame.to_pickle()(注意:对象必须是可选择的!).

要回答第二个问题,您可以将其转换回来ast.literal_eval:

>>> from ast import literal_eval
>>> literal_eval('[1.23, 2.34]')
[1.23, 2.34]
Run Code Online (Sandbox Code Playgroud)

  • @EdChum显然不是,因为在版本0.17.1中,我用`to_csv`和`from_csv`将`list`转换为`string`。 (2认同)

elP*_*tor 11

我刚遇到这个问题,有一个非常简单的解决方案(pandas.eval())。我正在使用熊猫 0.20.0。

# SETUP
import pandas as pd
import io

csv = io.StringIO(u'''
id  list
A1  [1,2]
A2  [3,4]
A3  [5,6]
''')

df = pd.read_csv(csv, delim_whitespace = True)

# TYPE CHECK <type 'str'>
print type(df.at[0, 'list'])

# MAIN CONVERSION
df['list'] = pd.eval(df['list'])

# TYPE CHECK <type 'list'>
print type(df.at[0, 'list'])
Run Code Online (Sandbox Code Playgroud)


Tre*_*ney 9

数据在 test.csv

col1
"[1.23, 2.34]"
"['KB4523205','KB4519569','KB4503308']"
Run Code Online (Sandbox Code Playgroud)

创建csv时转换列

from ast import literal_eval
import pandas as pd

# convert the column during import
df = pd.read_csv('test.csv', converters={'col1': literal_eval})

# display(df)
                                col1
0                       [1.23, 2.34]
1  [KB4523205, KB4519569, KB4503308]

# check type
print(type(df.iloc[0, 0]))
list

print(type(df.iloc[1, 0]))
list
Run Code Online (Sandbox Code Playgroud)

转换现有数据框的列

df.col1 = df.col1.apply(literal_eval)
Run Code Online (Sandbox Code Playgroud)