如何从 pandas 数据框中的大型每日 JSON 数据集计算平均月值?

Posted

技术标签:

【中文标题】如何从 pandas 数据框中的大型每日 JSON 数据集计算平均月值?【英文标题】:How can I compute average monthly value from large daily JSON dataset in pandas dataframe? 【发布时间】:2021-03-30 22:50:56 【问题描述】:

我对使用 pandas 数据框读取数据比较陌生,并且在处理我的数据集时遇到了一些问题。我一直在阅读许多其他关于类似问题的 *** 帖子,但我一直无法将这些解决方案应用于我的案例,这可能是因为我的 JSON 数据的结构。我的 JSON 数据排列在我的数据框 df = pd.DataFrame.from_records(data) 中通常看起来像这样

             dateTime                          value
0   01/16/20 04:32:42   'bpm': 70, 'confidence': 0
1   01/16/20 04:32:57   'bpm': 70, 'confidence': 0
2   01/16/20 04:33:12   'bpm': 70, 'confidence': 1
等等许多日常价值。

我的目标是读取所有这些原始每日数据并计算“bpm”的月平均值并绘制到 matplot 图。我的问题是我在使用 pandas datetime 或 mean() 操作时遇到问题,因为我认为 pandas 实际上不接受我的 dateTime 格式,当我尝试使用 mean() 时,它给了我一个 pandas.core.base.DataError: No numeric types to aggregate 错误。

我如何使用内置的 pandas 工具,通过根据月份将我的每日值分组在一起来计算每月平均值?

for file in os.listdir(data_dir):  # look at every file in the folder
    if file.startswith("heart_rate") and file.endswith(".json"):  # only want heart_rate-date.json files
        with open(os.path.join(data_dir, file)) as f:  # open each file in data_dir
            data = json.load(f)
            df = pd.DataFrame.from_records(data)
            print(df)
            #df.dateTime = pd.to_datetime(df.dateTime)
            #df['Month'] = df['dateTime'].dt.month
            for i, j in enumerate(data):
                if data[i]['value']['confidence'] > 0:
                    daily_avg_bpm += data[i]['value']['bpm']
                    daily_date = data[i]['dateTime'].split()[0]
                    my_date = datetime.datetime.strptime(daily_date, "%m/%d/%y").date()
                    days.append(my_date)
            months.append(daily_date[:2])
            daily_avg_bpm /= len(data)
            dates.append(daily_date)
            avg_bpms.append(round(daily_avg_bpm))
        f.close()
plt.xlabel('Month')
plt.ylabel('Heart Rate')
plt.title("Fitbit Heart Rate")
for i, j in enumerate(dates):
    plt.plot(dates[i], avg_bpms[i])
plt.show()

【问题讨论】:

resample 解决了您的问题吗? 嗨,Prayson,不幸的是还没有。我试图应用您的建议,但 apply() 出现错误,并且我一直在获取列表索引必须。现在我得到 DataError raise DataError("No numeric types to aggregate") pandas.core.base.DataError: No numeric types to aggregate. 这意味着您没有要重新采样的数值。 df.dtypes 得到什么? 我的数据框值看起来像我的问题中显示的带有日期时间和值的示例。我想要的数值是 ['values']['bpm'] 值,但 df.dtypes 给我一个错误 TypeError: 'Series' object is not callable 如您所见,您拥有的是 Series 而不是 DataFrame。所以示例数据不一样。你可以试试df['value'].apply(pd.Series) 吗?这会扩大价值吗? 【参考方案1】:

values 转换为列并将dateTime 转换为实际日期时间的最简单方法。这样您就可以使用resample 来汇总频率需求:

import pandas as pd

data = pd.DataFrame('dateTime':[ '01/16/20 04:32:42', '01/16/20 04:32:57', '02/16/20 04:33:12', '03/16/20 04:33:12'],
'value': ['bpm': 70, 'confidence': 0, 'bpm': 75, 'confidence': 0,  
          'bpm': 73, 'confidence': 1, 'bpm': 78, 'confidence': 1])

# expland 
df = data['value'].apply(pd.Series)

# to datetime and set index 
df['dateTime'] = pd.to_datetime(data['dateTime'])
df.set_index('dateTime', inplace=True)

# data resample to Monthy with mean 
example = df.resample('M', kind='period').mean()

# plot
example['bpm'].plot(title="Fitbit Heart Rate", xlabel="Month", ylabel="Heart Rate");

注意:

要显示图表,请确保您拥有 N > 1 的所选频率的数据。因此,如果 Month 的频率为“M”,请确保数据集中至少有 2 个月。

阅读Pandas resample 文档了解更多详情。

【讨论】:

UserWarning: Attempting to set identical left == right == 600.0 results in singular transformations; automatically expanding. ax.set_xlim(left, right) 并没有显示任何内容。 那是因为我们只有一个月的数据。所以你什么都看不到。将上面的日期更改为['01/16/20 04:32:42', '01/16/20 04:32:57', '02/16/20 04:33:12'],您将看到图表。注意:我有更新数据来反映它【参考方案2】:

我没有您的数据,因此这可能无法立即生效。但除了你应该可以使用这个方法。

步骤

    value 列的dict 值转换为列(Reference) 分组依据 (Reference) 平均 (Reference)
import pandas as pd

df = pd.DataFrame.from_records(data)
# Step 1
df = pd.concat([df.drop(['value'], axis=1), df['value'].apply(pd.Series)], axis=1)
# Step 2
df.groupby(by=[df.dateTime])
# Step 3
print(df['bpm'].mean().sort_values())

【讨论】:

我对 print(df['bpm'].mean().sort_values()) 这一行感到困惑,因为 df['bpm'].mean() 返回一个浮点值,所以这段代码会抛出错误 AttributeError: 'numpy.float64' object has no attribute 'sort_values' 你的意思是在一个列然后排序?

以上是关于如何从 pandas 数据框中的大型每日 JSON 数据集计算平均月值?的主要内容,如果未能解决你的问题,请参考以下文章

将 JSON 时间戳字符串转换为 pandas 数据框中的 python 日期

如何从按连续变量分层的 Pandas 数据框中获取分层随机样本

在 pandas 数据框中搜索和替换大型数据集

如何将 json 转换为 pandas 数据框?

如何将 json 加载到 pandas 数据框中?

Pandas - 在数据框中的列内扩展嵌套的 json 数组