【问题标题】:python pandas: list of integers as individual values of DataFramepython pandas:整数列表作为DataFrame的单个值
【发布时间】:2015-11-02 19:12:42
【问题描述】:

问题: 如何'pd.read_csv'使给定列中的值是类型列表(列表在一列的每一行)?

当创建一个 DataFrame(从一个 dict,见下文)时,单个值的类型是 list。问题:将 DataFrame 写入文件并从文件读取回 DataFrame 后,我得到一个字符串而不是列表。

创建数据框
import pandas as pd
dict2df = {"euNOG": ["ENOG410IF52", "KOG2956", "KOG1997"], 
           "neg": [[58], [1332, 753, 716, 782], [187]], 
           "pos": [[96], [659, 661, 705, 1228], [1414]]}
df = pd.DataFrame(dict2df)

值是一个列表

type(df.loc[0, 'neg']) == list # --> True
type(df.loc[0, 'neg']) == str # --> False
df.loc[1, 'neg'][-1] == 782 # --> True
写入文件
df.to_csv('DataFrame.txt', sep='\t', header=True, index=False)
从文件中读取
df = pd.read_csv('DataFrame.txt', sep='\t')

值是字符串而不是列表

type(df.loc[0, 'neg']) == list # --> False
type(df.loc[0, 'neg']) == str # --> True
df.loc[1, 'neg'][-1] == 782 # --> False

当然,可以在两种数据类型之间进行转换,但计算量大,需要额外的工作(见下文)

def convert_StringList2ListOfInt(string2convert):
    return [int(ele) for ele in string2convert[1:-1].split(',')]

def DataFrame_StringOfInts2ListOfInts(df, cols2convert_list):
    for column in cols2convert_list:
        column_temp = column + "_temp"
        df[column_temp] = df[column].apply(convert_StringList2ListOfInt, 1)
        df[column] = df[column_temp]
        df = df.drop(column_temp, axis=1)
    return df
df = DataFrame_StringOfInts2ListOfInts(df, ['neg', 'pos'])

什么是更好(更pythonic)的解决方案? 迭代列表中的整数非常方便,而不必来回转换它们。 感谢您的支持!!

【问题讨论】:

    标签: python list pandas


    【解决方案1】:

    您可以使用ast.literal_eval() 将字符串转换为列表。

    ast.literal_eval()的一个简单例子-

    >>> import ast
    >>> l = ast.literal_eval('[10,20,30]')
    >>> type(l)
    <class 'list'>
    

    对于您的情况,您可以将其传递给 Series.apply ,以便(安全地)评估系列中的每个元素。示例 -

    df = pd.read_csv('DataFrame.txt', sep='\t')
    import ast
    df['neg_list'] = df['neg'].apply(ast.literal_eval)
    df = df.drop('neg',axis=1)
    df['pos_list'] = df['pos'].apply(ast.literal_eval)
    df = df.drop('pos',axis=1)
    

    演示 -

    In [15]: import pandas as pd
    
    In [16]: dict2df = {"euNOG": ["ENOG410IF52", "KOG2956", "KOG1997"],
       ....:            "neg": [[58], [1332, 753, 716, 782], [187]],
       ....:            "pos": [[96], [659, 661, 705, 1228], [1414]]}
    
    In [17]: df = pd.DataFrame(dict2df)
    
    In [18]: df.to_csv('DataFrame.txt', sep='\t', header=True, index=False)
    
    In [19]: newdf = pd.read_csv('DataFrame.txt', sep='\t')
    
    In [20]: newdf['neg']
    Out[20]:
    0                     [58]
    1    [1332, 753, 716, 782]
    2                    [187]
    Name: neg, dtype: object
    
    In [21]: newdf['neg'][0]
    Out[21]: '[58]'
    
    In [22]: import ast
    
    In [23]: newdf['neg_list'] = newdf['neg'].apply(ast.literal_eval)
    
    In [24]: newdf = newdf.drop('neg',axis=1)
    
    In [25]: newdf['pos_list'] = newdf['pos'].apply(ast.literal_eval)
    
    In [26]: newdf = newdf.drop('pos',axis=1)
    
    In [27]: newdf
    Out[27]:
             euNOG               neg_list               pos_list
    0  ENOG410IF52                   [58]                   [96]
    1      KOG2956  [1332, 753, 716, 782]  [659, 661, 705, 1228]
    2      KOG1997                  [187]                 [1414]
    
    In [28]: newdf['neg_list'][0]
    Out[28]: [58]
    

    【讨论】:

    • 谢谢!从某种意义上说,这更像是 Pythonic,因为它使用库而不是我自己的代码。我希望在读取数据框时找到包含此转换的解决方案。
    猜你喜欢
    • 2017-11-08
    • 2019-11-28
    • 2021-05-26
    • 2022-01-01
    • 2018-03-27
    • 1970-01-01
    • 2020-03-19
    • 1970-01-01
    • 2013-06-14
    相关资源
    最近更新 更多