【问题标题】:pandas, combining multiple dataframes熊猫,结合多个数据框
【发布时间】:2015-04-09 14:52:03
【问题描述】:

我有一个执行以下操作的 python 程序。

  • 读取 .csv
  • 使用来自 csv 特定列的值创建一个数据框
  • 从 unix 时间戳转换时间戳
  • 按小时对数据进行分组,然后查找该小时内某些数据的平均值。

代码:

df = pd.read_csv(files,parse_dates=True)
df2 = df[['timestamp','avg_hr','avg_rr','emfit_sleep_summary_id']]
df2['timestamp'] = df2['timestamp'].astype(int)
df2['timestamp'] = pd.to_datetime(df2['timestamp'],unit='s')

df2 = df2.set_index('timestamp')
df3 = df2.groupby(df2.index.map(lambda t: t.hour))['avg_hr'].mean()
df4 = df2.groupby(df2.index.map(lambda t: t.hour))['avg_rr'].mean()

print df3
print df4

样本输出:

       timestamp         avg_hr  avg_rr    emfit_sleep_summary_id
0 2015-01-28 08:14:50     101     6.4                      78
1 2015-01-28 08:14:52      98     6.4                      78
2 2015-01-28 00:25:00      60     0.0                      78 
3 2015-01-28 00:25:02      63     0.0                      78
4 2015-01-28 07:24:06      79    11.6                      78
5 2015-01-28 07:24:08      79    11.6                      78
0    99.5
7    61.5
8    78.5
Name: avg_hr, dtype: float64
0     0.000
7    11.725
8     6.400
Name: avg_rr, dtype: float64

我现在尝试将 df3 和 df4 合并到 df2 中,因此结果将如下所示:

       timestamp         avg_hr  avg_rr    emfit_sleep_summary_id   AVG_HR    AVG_RR
0 2015-01-28 08:14:50     101     6.4                      78        99.5       6.4 
1 2015-01-28 08:14:52      98     6.4                      78        99.5       6.4
2 2015-01-28 00:25:00      60     0.0                      78        61.5       0.0
3 2015-01-28 00:25:02      63     0.0                      78        61.5       0.0
4 2015-01-28 07:24:06      79    11.6                      78        78.5       11.6
5 2015-01-28 07:24:08      79    11.6                      78        78.5       11.6

我尝试了以下操作

df2['AVG_HR'] = df2.groupby(df2.index.map(lambda t: t.hour))['avg_hr'].mean()

但是当我运行时,它为整个列返回了NAN。

编辑:我还知道如何将行数减少到每小时一个,而不是每小时 2 个。

       timestamp         avg_hr  avg_rr    emfit_sleep_summary_id   AVG_HR    AVG_RR
0 2015-01-28 08:14:50     101     6.4                      78        99.5       6.4 
1 2015-01-28 00:25:00      60     0.0                      78        61.5       0.0
2 2015-01-28 07:24:06      79    11.6                      78        78.5       11.6

【问题讨论】:

  • 我想你想要的是这个:df2['AVG_HR'] = df2.groupby(df2.index.map(lambda t: t.hour))['avg_hr'].transofrm('mean')你能确认一下
  • 另外,您不需要 lambda 来按小时分组:df3 = df2.groupby(df2.index.hour)['avg_hr'].mean()
  • @EdChum 有效,如果您可以将其发布为答案,我会接受。另外,想知道有没有办法减少行数?而不是每个时间戳有 2 个,我可以只有一个吗?
  • 所以您想将df2 减少到每小时一行?在哪种情况下,您想要聚合列的平均值还是总和? df2.groupby(df2.index.hour).mean().reset_index() 应该将 df 压缩到每小时一次,您也可以重新采样
  • 是的,我每小时需要一个,而不是 2 个时间戳。我希望平均值保持不变。请查看编辑。

标签: python csv pandas


【解决方案1】:

要从 groupby 添加聚合列,请使用 transform 这将返回与原始 df 对齐的 Series:

df2['AVG_HR'] = df2.groupby(df2.index.map(lambda t: t.hour))['avg_hr'].transofrm('mean')

另外,也不需要使用 lambda 来按小时分组,索引,如果是 DateTimeindex,则具有可以直接访问的 datetime 属性,因此可以将上述简化为:

df2['AVG_HR'] = df2.groupby(df2.index.hour)['avg_hr'].transform('mean')

如果您想按小时重新采样,您可以按小时分组,然后致电reset_index:

In [17]:

df.groupby(df.index.hour).mean().reset_index()
Out[17]:
   index  avg_hr  avg_rr  emfit_sleep_summary_id
0      0    61.5     0.0                      78
1      7    79.0    11.6                      78
2      8    99.5     6.4                      78

【讨论】:

  • 我想没有办法让日期时间停留?而不是0、7、8
  • 不使用 groupby,替代方法是在添加平均列后在您的 df 上调用 drop_duplicates,但这不会平均其他重复列
  • 我做到了df2 = df2.drop_duplicates(subset='AVG_HR',take_last=True) 并且成功了 :)
  • 但这不会平均说'avg_hr'虽然如果这是你想要的那很好,我会发布但认为你想平均所有值,你也可以投票;- )
  • 我使用 df2['AVG_HR'] = df2.groupby(df2.index.hour)['avg_hr'].transform('mean') 获得了 avg_hr,这将添加一个额外的列,我使用该列来过滤小时数。与 avg_rr 相同
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-03
  • 2023-02-10
  • 2018-07-22
  • 1970-01-01
  • 2017-06-11
相关资源
最近更新 更多