使用来自Zillow研究数据网站的数据,主要是城市级别的数据。数据结构包含6列城市相关信息和245列月销售价格。我使用以下代码显示了数据的样本:
import pandas as pd
from tabulate import tabulate
df = pd.read_csv("City_Zhvi_AllHomes.csv")
c = df.columns.tolist()
cols = c[:7]
cols.append(c[-1])
print (tabulate(df[cols].iloc[23:29], headers = 'keys', tablefmt = 'orgtbl'))
以上代码将打印出如下所示的示例:
| | RegionID | RegionName | State | Metro | CountyName | SizeRank | 1996-04 | 2016-08 |
|----+------------+---------------+---------+---------------+--------------+------------+-----------+-----------|
| 23 | 5976 | Milwaukee | WI | Milwaukee | Milwaukee | 24 | 68100 | 99500 |
| 24 | 7481 | Tucson | AZ | Tucson | Pima | 25 | 91500 | 153000 |
| 25 | 13373 | Portland | OR | Portland | Multnomah | 26 | 121100 | 390500 |
| 26 | 33225 | Oklahoma City | OK | Oklahoma City | Oklahoma | 27 | 64900 | 130500 |
| 27 | 40152 | Omaha | NE | Omaha | Douglas | 28 | 88900 | 143800 |
| 28 | 23429 | Albuquerque | NM | Albuquerque | Bernalillo | 29 | 115400 | 172000 |
df
的一部分是时间序列,关键在于将时间相关的列与其他列分开,使用pandas
中的resample
和to_datetime
方法。
假设我们只对1998-2000年的销售额进行总结,
这将使我们能够选择列。
# seperate time columns and convert their names to datetime
tdf = df[df.columns[6:]].rename(columns=pd.to_datetime)
# find the columns in the period 1998-2000
cols = tdf.columns
sel_cols = cols[(cols > '1997-12-31') & (cols < '2000')]
# select the columns, resample on columns
# calculate the mean
# rename the columns the way we like
mdf = tdf[sel_cols].resample('6M',axis=1).mean().rename(
columns=lambda x: '{:}${:}'.format(x.year, [1, 2][x.quarter > 2]))
# reattach non-time columns
mdf[df.columns[:6]] = df[df.columns[:6]]
print (tabulate(mdf[mdf.columns[0:9]].iloc[
23:29], headers='keys', tablefmt='orgtbl'))
上面的代码将会打印如下所示的一个样例:
| | 1998$1 | 1998$2 | 1999$1 | 1999$2 | 2000$1 | RegionID | RegionName | State | Metro |
|----+----------+----------+----------+----------+----------+------------+---------------+---------+---------------|
| 23 | 71900 | 72483.3 | 72616.7 | 74266.7 | 75920 | 5976 | Milwaukee | WI | Milwaukee |
| 24 | 94200 | 95133.3 | 96533.3 | 99100 | 100600 | 7481 | Tucson | AZ | Tucson |
| 25 | 139000 | 141900 | 145233 | 148900 | 151980 | 13373 | Portland | OR | Portland |
| 26 | 68500 | 69616.7 | 72016.7 | 73616.7 | 74900 | 33225 | Oklahoma City | OK | Oklahoma City |
| 27 | 98200 | 99250 | 103367 | 109083 | 112160 | 40152 | Omaha | NE | Omaha |
| 28 | 121000 | 122050 | 122833 | 123633 | 124420 | 23429 | Albuquerque | NM | Albuquerque |
问题是:
重新取样结果的最后一列显示了年份“2000”,尽管选择的是<'2000',为什么会这样呢?
编辑: 只是为了好玩,我包括了一种更“pandorable”的方法来完成上述操作。
import pandas as pd
housing = pd.read_csv('City_Zhvi_AllHomes.csv',
index_col=list(range(6))).filter(
regex='199[8-9]-[0-1][0-9]').rename(
columns=pd.to_datetime).resample('2Q',
closed='left',axis=1).mean().rename(
columns=lambda x: str(x.to_period('2Q')).replace(
'Q','$').replace('2','1').replace('4','2')).reset_index()
这将会得到我们想要的结果,
housing.iloc[23:27,4:]
的输出如下所示。| | CountyName | SizeRank | 1998$1 | 1998$2 | 1999$1 | 1999$2 |
|----+--------------+------------+----------+----------+----------+----------|
| 23 | Milwaukee | 24 | 72366.7 | 72583.3 | 73916.7 | 75750 |
| 24 | Pima | 25 | 94883.3 | 96183.3 | 98783.3 | 100450 |
| 25 | Multnomah | 26 | 141167 | 144733 | 148183 | 151767 |
| 26 | Oklahoma | 27 | 69300 | 71550 | 73466.7 | 74766.7 |
tdf[sel_cols].resample('6M', axis=1).mean().rename
替换tdf[sel_cols].T.resample('6M').mean().T.rename
中的axis=1
参数。 - jezrael