将字典列表转换为PandasDataFrame

nwnhqdif  于 2023-02-11  发布在  其他
关注(0)|答案(7)|浏览(527)

如何将字典列表转换为DataFrame

[{'points': 50, 'time': '5:00', 'year': 2010}, 
 {'points': 25, 'time': '6:00', 'month': "february"}, 
 {'points':90, 'time': '9:00', 'month': 'january'}, 
 {'points_h1':20, 'month': 'june'}]

我想把上面的代码转换成一个DataFrame

month  points  points_h1  time  year
0       NaN      50        NaN  5:00  2010
1  february      25        NaN  6:00   NaN
2   january      90        NaN  9:00   NaN
3      june     NaN         20   NaN   NaN

注:列的顺序无关紧要。

3z6pesqy

3z6pesqy1#

**Pyhton3:**前面列出的大多数解决方案都有效。但是,有时不需要 Dataframe 的row_number,并且必须单独写入每行(记录)。

在这种情况下,下面的方法很有用。

import csv

my file= 'C:\Users\John\Desktop\export_dataframe.csv'

records_to_save = data2 #used as in the thread. 

colnames = list[records_to_save[0].keys()] 
# remember colnames is a list of all keys. All values are written corresponding
# to the keys and "None" is specified in case of missing value 

with open(myfile, 'w', newline="",encoding="utf-8") as f:
    writer = csv.writer(f)
    writer.writerow(colnames)
    for d in records_to_save:
        writer.writerow([d.get(r, "None") for r in colnames])
liwlm1x9

liwlm1x92#

我发现的最简单的方法是这样的:

dict_count = len(dict_list)
df = pd.DataFrame(dict_list[0], index=[0])
for i in range(1,dict_count-1):
    df = df.append(dict_list[i], ignore_index=True)
eqqqjvef

eqqqjvef3#

我有以下带有datetime键和int值的指令列表:

list = [{datetime.date(2022, 2, 10): 7}, {datetime.date(2022, 2, 11): 1}, {datetime.date(2022, 2, 11): 1}]

我遇到了一个问题,用上面的方法将其转换为Dataframe,因为它创建了带有日期列的Dataframe ...
我的解决方案:

df = pd.DataFrame()
for i in list:
    temp_df = pd.DataFrame.from_dict(i, orient='index')
    df = df.append(temp_df)
5fjcxozz

5fjcxozz4#

如果dsdict的列表:

df = pd.DataFrame(ds)

注意:这不适用于嵌套数据。

kb5ga3dv

kb5ga3dv5#

如何将字典列表转换为PandasDataFrame?

其他的答案都是正确的,但是对于这些方法的优点和局限性解释得并不多。这篇文章的目的是展示这些方法在不同情况下的例子,讨论什么时候使用(什么时候不使用),并提出替代方法。

DataFrame()DataFrame.from_records().from_dict()

根据数据的结构和格式,有时这三种方法都有效,有时某些方法比其他方法更有效,有时某些方法根本不起作用。
考虑一个非常人为的例子。

np.random.seed(0)
data = pd.DataFrame(
    np.random.choice(10, (3, 4)), columns=list('ABCD')).to_dict('r')

print(data)
[{'A': 5, 'B': 0, 'C': 3, 'D': 3},
 {'A': 7, 'B': 9, 'C': 3, 'D': 5},
 {'A': 2, 'B': 4, 'C': 7, 'D': 6}]

这个列表由所有键都存在的"记录"组成,这是你可能遇到的最简单的情况。

# The following methods all produce the same output.
pd.DataFrame(data)
pd.DataFrame.from_dict(data)
pd.DataFrame.from_records(data)

   A  B  C  D
0  5  0  3  3
1  7  9  3  5
2  2  4  7  6
词典方向上的单词:x一米三英寸/x一米四英寸

在继续之前,区分不同类型的字典方向和Pandas支持很重要。主要有两种类型:"列"和"索引"。
orient='columns'
具有"列"方向的字典将使它们的键与等效DataFrame中的列相对应。
例如,上面的data位于"列"方向。
一个二个一个一个
注意:如果您使用pd.DataFrame.from_records,方向将被假定为"列"(您不能指定其他方向),字典将相应地加载。
orient='index'
在这个方向上,键被假定为对应于索引值,这种类型的数据最适合pd.DataFrame.from_dict

data_i ={
 0: {'A': 5, 'B': 0, 'C': 3, 'D': 3},
 1: {'A': 7, 'B': 9, 'C': 3, 'D': 5},
 2: {'A': 2, 'B': 4, 'C': 7, 'D': 6}}
pd.DataFrame.from_dict(data_i, orient='index')

   A  B  C  D
0  5  0  3  3
1  7  9  3  5
2  2  4  7  6

OP中未考虑该病例,但了解该病例仍然有用。

设置自定义索引

如果需要对结果DataFrame进行自定义索引,可以使用index=...参数进行设置。

pd.DataFrame(data, index=['a', 'b', 'c'])
# pd.DataFrame.from_records(data, index=['a', 'b', 'c'])

   A  B  C  D
a  5  0  3  3
b  7  9  3  5
c  2  4  7  6

pd.DataFrame.from_dict不支持此功能。

处理缺少的键/列

当处理缺少键/列值的字典时,所有方法都是现成的。

data2 = [
     {'A': 5, 'C': 3, 'D': 3},
     {'A': 7, 'B': 9, 'F': 5},
     {'B': 4, 'C': 7, 'E': 6}]
# The methods below all produce the same output.
pd.DataFrame(data2)
pd.DataFrame.from_dict(data2)
pd.DataFrame.from_records(data2)

     A    B    C    D    E    F
0  5.0  NaN  3.0  3.0  NaN  NaN
1  7.0  9.0  NaN  NaN  NaN  5.0
2  NaN  4.0  7.0  NaN  6.0  NaN

正在读取列的子集

"如果我不想读取每一列该怎么办"?您可以使用columns=...参数轻松地指定这一点。
例如,在上面的data2示例字典中,如果您只想读取列"A"、"D"和"F",可以通过传递一个列表来实现:

pd.DataFrame(data2, columns=['A', 'D', 'F'])
# pd.DataFrame.from_records(data2, columns=['A', 'D', 'F'])

     A    D    F
0  5.0  3.0  NaN
1  7.0  NaN  5.0
2  NaN  NaN  NaN

默认方向为"columns"的pd.DataFrame.from_dict不支持此操作。

pd.DataFrame.from_dict(data2, orient='columns', columns=['A', 'B'])
ValueError: cannot use columns parameter with orient='columns'

正在读取行的子集

这些方法 * 直接 * 都不支持。您必须迭代数据,并在迭代时就地执行reverse delete。例如,要从上面的data2中只提取第0行和第2行,可以使用:

rows_to_select = {0, 2}
for i in reversed(range(len(data2))):
    if i not in rows_to_select:
        del data2[i]

pd.DataFrame(data2)
# pd.DataFrame.from_dict(data2)
# pd.DataFrame.from_records(data2)

     A    B  C    D    E
0  5.0  NaN  3  3.0  NaN
1  NaN  4.0  7  NaN  6.0

万灵药:嵌套数据的json_normalize

json_normalize函数是上述方法的一个强大、健壮的替代方法,它处理字典(记录)列表,此外还可以处理嵌套字典。
一个一个三个一个一个
同样,请记住传递给json_normalize的数据需要采用字典(记录)列表格式。
如前所述,json_normalize还可以处理嵌套字典,下面是取自文档的一个示例。

data_nested = [
  {'counties': [{'name': 'Dade', 'population': 12345},
                {'name': 'Broward', 'population': 40000},
                {'name': 'Palm Beach', 'population': 60000}],
   'info': {'governor': 'Rick Scott'},
   'shortname': 'FL',
   'state': 'Florida'},
  {'counties': [{'name': 'Summit', 'population': 1234},
                {'name': 'Cuyahoga', 'population': 1337}],
   'info': {'governor': 'John Kasich'},
   'shortname': 'OH',
   'state': 'Ohio'}
]
pd.json_normalize(data_nested, 
                          record_path='counties', 
                          meta=['state', 'shortname', ['info', 'governor']])

         name  population    state shortname info.governor
0        Dade       12345  Florida        FL    Rick Scott
1     Broward       40000  Florida        FL    Rick Scott
2  Palm Beach       60000  Florida        FL    Rick Scott
3      Summit        1234     Ohio        OH   John Kasich
4    Cuyahoga        1337     Ohio        OH   John Kasich

有关metarecord_path参数的详细信息,请查看文档。

总结

下面是上面讨论的所有方法以及支持的特性/功能的表格。

  • 使用orient='columns',然后转置以获得与orient='index'相同的效果。
1szpjjfi

1szpjjfi6#

在Pandas16.2中,我必须执行pd.DataFrame.from_records(d)才能让它工作。

c0vxltue

c0vxltue7#

您还可以将pd.DataFrame.from_dict(d)用作:

In [8]: d = [{'points': 50, 'time': '5:00', 'year': 2010}, 
   ...: {'points': 25, 'time': '6:00', 'month': "february"}, 
   ...: {'points':90, 'time': '9:00', 'month': 'january'}, 
   ...: {'points_h1':20, 'month': 'june'}]

In [12]: pd.DataFrame.from_dict(d)
Out[12]: 
      month  points  points_h1  time    year
0       NaN    50.0        NaN  5:00  2010.0
1  february    25.0        NaN  6:00     NaN
2   january    90.0        NaN  9:00     NaN
3      june     NaN       20.0   NaN     NaN

相关问题