【问题标题】:Data structure manipulation with Pandas使用 Pandas 进行数据结构操作
【发布时间】:2015-09-03 21:09:53
【问题描述】:

我有一个字典列表如下:

[
{
    "status": "BV", 
    "max_total_duration": null, 
    "min_total_duration": null, 
    "75th_percentile": 420, 
    "median": 240.0, 
    "25th_percentile": 180, 
    "avg_total_duration": null
}, 
{
    "status": "CORR", 
    "max_total_duration": null, 
    "min_total_duration": null, 
    "75th_percentile": 1380, 
    "median": 720.0, 
    "25th_percentile": 420, 
    "avg_total_duration": null
}, 
{
    "status": "FILL", 
    "max_total_duration": null, 
    "min_total_duration": null, 
    "75th_percentile": 1500, 
    "median": 840.0, 
    "25th_percentile": 480, 
    "avg_total_duration": null
}, 
{
    "status": "INIT", 
    "max_total_duration": 11280, 
    "min_total_duration": 120, 
    "75th_percentile": 720, 
    "median": 360.0, 
    "25th_percentile": 180, 
    "avg_total_duration": 2061
}, 
]

显然,所有状态的 max_total_duration、min_total_duration 和 avg_total_duration 均为空,除非状态为“INIT”。我想要的是删除所有空值和 INIT 的所有条目,其中 max_total_duration、min_total_duration 和 avg_total_duration 具有正确的值,将它们作为新字典添加到列表中,如下所示:

[
{
    "status": "BV", 
    "75th_percentile": 420, 
    "median": 240.0, 
    "25th_percentile": 180, 
}, 
{
    "status": "CORR", 
    "75th_percentile": 1380, 
    "median": 720.0, 
    "25th_percentile": 420, 
}, 
{
    "status": "FILL", 
    "75th_percentile": 1500, 
    "median": 840.0, 
    "25th_percentile": 480, 
}, 
{
    "status": "INIT", 
    "75th_percentile": 720, 
    "median": 360.0, 
    "25th_percentile": 180, 

}, 
{
    "max_total_duration": 11280, 
    "min_total_duration": 120,
    "avg_total_duration": 2061,
}
]    

我已经尝试通过迭代列表来完成此操作,但计算成本非常高。有没有更简单的方法可以使用 pandas 来执行此操作?

【问题讨论】:

  • 为什么投反对票?我能有理由吗
  • 您还没有为自己解决问题做出任何努力。您只是粘贴了数据并要求其他人使用不同的库为您解决问题。为什么不尝试将一些数据放入 pandas 中,看看是否卡住,然后然后问一个具体问题?
  • 嗯..我确实尝试过使用传统的方法遍历列表,找到空值,消除它们并获得所需的结果..我对熊猫没有经验..如果那是什么它需要..让我尝试通过 pandas 看看我是否可以自己解决它..
  • 没有使用工具的经验并不是提出一个仅包含“我如何解决这个我尝试了不同的方法,但使用该工具的问题?”的问题的正当理由。这是一个很好的问题——只要你通过尝试一些东西来支持它。
  • 您可以做的一件事是'from numpy import nan as null',然后当数据加载到DataFrame中时,某些列具有nan值,可以使用frame.dropna(axis = 1)删除。

标签: python list dictionary pandas


【解决方案1】:
data =[
{
    "status": "BV", 
    "max_total_duration": None, 
    "min_total_duration": None, 
    "75th_percentile": 420, 
    "median": 240.0, 
    "25th_percentile": 180, 
    "avg_total_duration": None
}, 
{
    "status": "CORR", 
    "max_total_duration": None, 
    "min_total_duration": None, 
    "75th_percentile": 1380, 
    "median": 720.0, 
    "25th_percentile": 420, 
    "avg_total_duration": None
}, 
{
    "status": "FILL", 
    "max_total_duration": None, 
    "min_total_duration": None, 
    "75th_percentile": 1500, 
    "median": 840.0, 
    "25th_percentile": 480, 
    "avg_total_duration": None
}, 
{
    "status": "INIT", 
    "max_total_duration": 11280, 
    "min_total_duration": 120, 
    "75th_percentile": 720, 
    "median": 360.0, 
    "25th_percentile": 180, 
    "avg_total_duration": 2061
}, 
]

data = [{key: val for key, val in d.iteritems() if val} for d in data]

final = []
for d in data:
    status = d.get('status')
    if status == 'INIT':
        final.append({'max_total_duration': d.get('max_total_duration'), 'min_total_duration': d.get('min_total_duration'), 'avg_total_duration': d.get('avg_total_duration')})
        del d['max_total_duration']
        del d['min_total_duration']
        del d['avg_total_duration']
    final.append(d)
print final

【讨论】:

  • @Cody..thanks for that..但我一直在寻找使用 pandas 的替代品
【解决方案2】:
import pandas as pd

# Substituting your 'null' for 'None'
df = pd.DataFrame(data)

>>> df
   25th_percentile  75th_percentile  avg_total_duration  max_total_duration  \
0              180              420                 NaN                 NaN
1              420             1380                 NaN                 NaN
2              480             1500                 NaN                 NaN
3              180              720                2061               11280

   median  min_total_duration status
0     240                 NaN     BV
1     720                 NaN   CORR
2     840                 NaN   FILL
3     360                 120   INIT

获取百分位数部分:

df_percentiles = df[['status','25th_percentile','median','75th_percentile']]

>>> df_percentiles
  status  25th_percentile  median  75th_percentile
0     BV              180     240              420
1   CORR              420     720             1380
2   FILL              480     840             1500
3   INIT              180     360              720

获取持续时间部分:

df_durations = df[df['status'] == 'INIT'][['max_total_duration','min_total_duration','avg_total_duration']]

>>> df_durations
   max_total_duration  min_total_duration  avg_total_duration
3               11280                 120                2061

循环并合并到列表中:

summary = df_percentiles.T.to_dict().values()

summary.append(df_durations.T.to_dict().values())

>>> summary
[{'25th_percentile': 180,
  '75th_percentile': 420,
  'median': 240.0,
  'status': 'BV'},
 {'25th_percentile': 420,
  '75th_percentile': 1380,
  'median': 720.0,
  'status': 'CORR'},
 {'25th_percentile': 480,
  '75th_percentile': 1500,
  'median': 840.0,
  'status': 'FILL'},
 {'25th_percentile': 180,
  '75th_percentile': 720,
  'median': 360.0,
  'status': 'INIT'},
 {'avg_total_duration': 2061.0,
  'max_total_duration': 11280.0,
  'min_total_duration': 120.0}]

【讨论】:

  • 在从 Mr.F 那里得到洗礼之后,我实际上是在浏览 Pandas 文档并试图解决这个问题..但这只是完美的,正是我所需要的..只是为了更好地理解这一点。 ..Pandas 如何使它比传统的循环迭代更快并解决这个问题..
  • 我的理解是 Pandas 是基于 numpy 数组的,因此它的性能提高了我在整个列表上的工作。如果是这种情况,那么最后两个步骤是否迭代列表并将它们组合起来不会破坏目的..没有组合 2 个列表的“熊猫”方式吗?
  • 我已将最后一步转换为不再是循环,而是直接保存到列表中。 AFAIK,您必须将这两个部分分开并附加为列表,因为感兴趣的列不同,否则转换为字典将包括 NaNs。可能有办法,但我不知道。另外,我鼓励您继续阅读 Pandas 文档/教程,因为它确实是一个非常有用且用途广泛的库。
猜你喜欢
  • 2017-12-18
  • 2018-05-04
  • 2019-06-26
  • 2010-12-30
  • 2019-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-20
相关资源
最近更新 更多