关于python:从列表或dict创建Pandas DataFrame始终返回空DF

Creating Pandas DataFrame from list or dict always returns empty DF

我正试图用字典创建一个熊猫数据框架。字典键是字符串,值是1个或多个列表。我遇到了一个奇怪的问题,在这个问题中pd.dataframe()命令总是返回一个空的数据帧,即使当我将它传递给一个非空的对象(如list或dict)时也是如此。我的代码类似于以下内容:

1
2
myDictionary = {"ID1":[1,2,3],"ID2":[10,11,12],[2,34,11],"ID3":[8,3,12]}
df = pd.DataFrame(myDictionary, columns = ["A","B","C"])

所以我想创建一个这样的df:

1
2
3
4
5
    A  B  C
ID1 1  2  3
ID2 10 11 12
ID2 2  34 11
ID3 8  3  12

当我检查df的内容时,我得到"空数据帧",如果我迭代它的内容,我只得到列名,而没有得到mydictionary中的任何数据!我已经检查了文档,这应该是一个StrightForward命令:

1
pd.DataFrame(dict, columns)

这并不能让我得到我想要的结果,我也不明白为什么。有人有什么想法吗?谢谢您!


在这种情况下,我建议您将列表解释为字符串。稍后,如果您需要编辑或分析其中的任何一个,您可以使用解析器来解释列。

请参阅下面的工作代码,它允许您将列表保存在数据框中。

1
2
3
4
5
6
myDictionary = {"ID1":'[1,2,3]',"ID2":'[10,11,12],[2,34,11]',"ID3":'[8,3,12]'}


df = pd.DataFrame(myDictionary, columns = ["ID1","ID2","ID3"], index = [0])
df.rename(columns ={'ID1' : 'A', 'ID2': 'B', 'ID3': 'C'}, inplace = True)
df.head(3)

通过始终将列表转换为字符串,您将能够更容易地组合它们,而不管需要组合多少列表。


请尝试下面的示例,找出df为空的原因:

1
2
myDictionary = {"ID1":[1,2,3],"ID2":[10,11,12],"ID3":[8,3,12], 'A':[0, 0, 0]}
df = pd.DataFrame(myDictionary, columns = ["A","B","C"])

你想要的是:

1
2
myDictionary = {"ID1":[1,2,3],"ID2":[10,11,12],"ID3":[8,3,12]}
df = pd.DataFrame(myDictionary).rename(columns={'ID1':'A', 'ID2':'B', 'ID3':'C'})


这里有一种可能的方法

词典

1
myDictionary = {"ID1":[1,2,3],"ID2":[[10,11,12],[2,34,11]],"ID3":[8,3,12]}

获取一个字典d,其中包含属于嵌套列表(a)键唯一的值的键值-使用后缀确保该字典d键唯一,以及(b)其值是嵌套列表中扁平的子列表。

  • 为此,循环并
    • 检查值是否包含子列表
      • 如果是,将该key:value对附加到单独的字典d中。
        • 使用后缀来分隔相同的键,因为键ID2不能在字典中重复。
          • 每个后缀将包含嵌套列表中的一个子列表
        • 从原始字典生成键列表(在名为nested_keysmyDictionary的变量中),该变量的值是嵌套列表
1
2
3
4
5
6
7
8
9
10
d = {}
nested_keys = []
for k,v in myDictionary.items():
    if any(isinstance(i, list) for i in v):
        for m,s in enumerate(v):
            d[k+'_'+str(m+1)] = s
        nested_keys.append(k)

print(d)
{'ID2_1': [10, 11, 12], 'ID2_2': [2, 34, 11]}

(使用值为嵌套列表的键列表-nested_keys)获取包含非嵌套列表值的第二个字典-有关如何执行此操作,请参阅本文

1
2
3
4
myDictionary = {key: myDictionary[key] for key in myDictionary if key not in nested_keys}

print(myDictionary)
{'ID1': [1, 2, 3], 'ID3': [8, 3, 12]}

将上面的两个词典合并为一个词典

1
2
3
4
myDictionary = {**d, **myDictionary}

print(myDictionary)
{'ID2_1': [10, 11, 12], 'ID2_2': [2, 34, 11], 'ID1': [1, 2, 3], 'ID3': [8, 3, 12]}

将组合字典转换为DataFrame并删除前面添加的后缀

1
2
3
4
5
6
7
8
9
10
11
12
df = pd.DataFrame(list(myDictionary.values()), index=myDictionary.keys(),
                                                columns=list('ABC'))
df.reset_index(inplace=True)
df = df.replace(r"_[0-9]","", regex=True)
df.sort_values(by='index', inplace=True)

print(df)
  index   A   B   C
2   ID1   1   2   3
0   ID2  10  11  12
1   ID2   2  34  11
3   ID3   8   3  12


不能创建两行级别相同的数据帧,例如

1
2
ID2 10 11 12
ID2 2  34 11

同时,字典也是如此,在字典中,每个键都必须是唯一的,但是在你的数据框架中,就像下面的字典一样,这是不可能的。

1
{"ID2":[10,11,12],"ID2":[2,34,11]}

所以我建议查你字典设计和遵循这么多关于将词汇转换为df的答案


首先,[2,34,11]列表缺少列名。给它起个名字!

出现错误的原因是使用以下命令时:

1
df = pd.DataFrame(myDictionary, columns = ["A","B","C"])

它基于您的字典创建一个数据帧。但你的意思是,你只需要字典中标记为"a"、"b"、"c"的列,而字典中没有这些列。

试试看:

1
2
df = pd.DataFrame(myDictionary, columns = ["ID1","ID2","ID3"])
df.rename(columns ={'ID1' : 'A', 'ID2': 'B', 'ID3': 'C'}, inplace = True)


您正在将名称"id1"、"id2"和"id3"作为列名称传入pd.dataframe,然后告诉熊猫使用列A、B、C。由于没有列A、B,C熊猫返回空数据框。使用下面的代码生成数据帧:

1
2
3
4
5
import pandas as pd

myDictionary = {"ID1": [1, 2, 3],"ID2": [10, 11, 12],"ID3": [8, 3, 12]}
df = pd.DataFrame(myDictionary, columns=["ID1","ID2","ID3"])
print(df)

输出:

1
2
3
4
   ID1  ID2  ID3
0    1   10    8
1    2   11    3
2    3   12   12

更重要的是:

1
"ID2":[10,11,12],[2,34,11]

不正确,因为您试图为字典中的一个值传递2个键,或者忘记为值生成键[2,34,11]。因此,当您尝试编译时,您的字典应该返回错误,除非您删除该列表。