Python:来自dict系列的Pandas数据帧

mak*_*mbi 17 python dataframe pandas

我有一个Pandas数据帧:

type(original)
pandas.core.frame.DataFrame
Run Code Online (Sandbox Code Playgroud)

其中包括系列对象original['user']:

type(original['user'])
pandas.core.series.Series
Run Code Online (Sandbox Code Playgroud)

original['user'] 指向一些dicts:

type(original['user'].ix[0])
dict
Run Code Online (Sandbox Code Playgroud)

每个dict都有相同的键:

original['user'].ix[0].keys()

[u'follow_request_sent',
 u'profile_use_background_image',
 u'profile_text_color',
 u'id',
 u'verified',
 u'profile_location',
 # ... keys removed for brevity
]
Run Code Online (Sandbox Code Playgroud)

以上是user来自tweeter API的推文中字段的一部分(的一部分).我想从这些dicts构建一个数据框.

当我尝试直接创建数据框时,每行只得到一列,此列包含整个dict:

pd.DataFrame(original['user'][:2])
    user
0   {u'follow_request_sent': False, u'profile_use_...
1   {u'follow_request_sent': False, u'profile_use_..
Run Code Online (Sandbox Code Playgroud)

当我尝试使用from_dict()创建数据框时,我得到相同的结果:

pd.DataFrame.from_dict(original['user'][:2])

    user
0   {u'follow_request_sent': False, u'profile_use_...
1   {u'follow_request_sent': False, u'profile_use_..
Run Code Online (Sandbox Code Playgroud)

接下来我尝试了一个列表理解,它返回了一个错误:

item = [[k, v] for (k,v) in users]
ValueError: too many values to unpack
Run Code Online (Sandbox Code Playgroud)

当我从单行创建数据框时,它几乎可以工作:

df = pd.DataFrame.from_dict(original['user'].ix[0])
df.reset_index()

    index   contributors_enabled    created_at  default_profile     default_profile_image   description     entities    favourites_count    follow_request_sent     followers_count     following   friends_count   geo_enabled     id  id_str  is_translation_enabled  is_translator   lang    listed_count    location    name    notifications   profile_background_color    profile_background_image_url    profile_background_image_url_https  profile_background_tile     profile_image_url   profile_image_url_https     profile_link_color  profile_location    profile_sidebar_border_color    profile_sidebar_fill_color  profile_text_color  profile_use_background_image    protected   screen_name     statuses_count  time_zone   url     utc_offset  verified
0   description     False   Mon May 26 11:58:40 +0000 2014  True    False       {u'urls': []}   0   False   157
Run Code Online (Sandbox Code Playgroud)

它几乎像我想要的那样工作,除了它将description字段设置为默认索引.

每个dicts有40个键,但我只需要大约10个,我在数据帧中有28734行.

如何过滤掉我不需要的按键?

Eya*_*yad 15

我想做的是以下内容:

new_df = pd.DataFrame(list(original['user']))
Run Code Online (Sandbox Code Playgroud)

这会将系列转换为list然后将其传递给pandas数据帧,它应该处理其余部分.

  • 我建议也保留原始索引, `new_df = pd.DataFrame(original['user'].tolist(), index=original.index)` (4认同)

小智 10

df = original['user'].apply(pd.Series)

效果很好

信用

  • 另外这可能真的很慢 (2认同)
  • 真的非常慢。在我对 5000 个字符串的测试中,`series.apply(pd.Series)` 比 `pd.DataFrame(series.values.tolist())` 慢 300 倍 (!)。似乎为每个字符串构建 Series 的成本很高。 (2认同)

Nic*_*ews 6

这有效:

series_of_dicts = original['user']
df = pd.DataFrame.from_records(
    series_of_dicts.values, index=series_of_dicts.index
)
Run Code Online (Sandbox Code Playgroud)

或者,如果您有一个列表或其他可迭代的字典,那么一个简单的

pd.DataFrame.from_records(iterable_of_dicts)

作品。

DataFrame.from_records 的文档

我没有计时,但我想它应该很快,因为这正是 DataFrame.from_records() 的用途。