使用Zillow的住房价值数据,我的数据框有一系列yyyy-mm形式的列名,例如
2001-01|2000-02|2000-03|2000-04|...|2016-08
这些列中的每一列都包含许多城市,州组合的该期间的平均房屋价值
RegionName State 2000-01 2000-02 2000-03
Philadelphia PA 53100 53200 53400
我需要对列进行分组,但是它们各自的四分之一,提供一个平均值并将其返回到新的数据帧。因此,对于提供的示例,我将具有类似以下内容
RegionName State 2000q1 2000q2 2000q3 2000q4
Philadelphia PA 53233.33 ... ... ...
我不知道如何开始解决这个问题。我可以拉出列名,获取最后两个字符,并将它们映射到包含季度数字的字典,但就是这样。不确定如何重新组装数据
非常感谢任何帮助
答案 0 :(得分:1)
这类似于MaxU's answer,但展示了一种方法,可以将 日期列和分组为非日期列(RegionName
, State
)。
import numpy as np
import pandas as pd
df = pd.DataFrame({'2000-01': [53100], '2000-02': [53200], '2000-03': [53400], 'RegionName': ['Philadelphia'], 'State': ['PA']})
melted = pd.melt(df, id_vars=['RegionName', 'State'], var_name='date')
melted['date'] = pd.PeriodIndex(melted['date'], freq='Q')
result = melted.groupby(['RegionName', 'State', 'date']).mean()
result = result['value'].unstack('date')
产量
date 2000Q1
RegionName State
Philadelphia PA 53233
首先,使用pd.melt
将所有日期列合并为一列:
import numpy as np
import pandas as pd
df = pd.DataFrame({'2000-01': [53100], '2000-02': [53200], '2000-03': [53400], 'RegionName': ['Philadelphia'], 'State': ['PA']})
melted = pd.melt(df, id_vars=['RegionName', 'State'], var_name='date')
# RegionName State date value
# 0 Philadelphia PA 2000-01 53100
# 1 Philadelphia PA 2000-02 53200
# 2 Philadelphia PA 2000-03 53400
接下来,使用pd.PeriodIndex
将日期(字符串?)转换为pd.Period
s。请注意,pd.PeriodIndex
可以将不同的日期字符串转换为相同的句点:
melted['date'] = pd.PeriodIndex(melted['date'], freq='Q')
# RegionName State date value
# 0 Philadelphia PA 2000Q1 53100
# 1 Philadelphia PA 2000Q1 53200
# 2 Philadelphia PA 2000Q1 53400
最后,使用groupby/mean
将具有相同RegionName
,State
和date
的行组合在一起,并计算每个组的平均值:
result = melted.groupby(['RegionName', 'State', 'date']).mean()
# value
# RegionName State date
# Philadelphia PA 2000Q1 53233
如果你在此停留,你的DataFrame将会整洁(PDF) - 每行代表一个“观察”。这通常是进一步计算的最佳形式。 (这个解决方案的第一步是将原始DataFrame转换为整洁格式并非偶然 - 请注意melted
也具有每行代表一个观察的属性。)
但是,如果您愿意,可以将date
索引级别移到单独的列中:
result = result['value'].unstack('date')