Python 如何在列名为带后缀的日期时间字符串的数据帧列上进行操作?
最后,我试图计算并绘制2010年至2016年美国290个县的住房需求价格弹性图 需求弹性等于数量变化百分比除以价格变化百分比 我拥有的数据来自Zillow:“InventoryMeasure_County_Public.csv”和“City_Zhvi_AllHomes.csv” 数据位于包含时间序列数据的多索引数据帧中。它看起来是这样的,虽然有55列和290行:Python 如何在列名为带后缀的日期时间字符串的数据帧列上进行操作?,python,pandas,dataframe,generator,Python,Pandas,Dataframe,Generator,最后,我试图计算并绘制2010年至2016年美国290个县的住房需求价格弹性图 需求弹性等于数量变化百分比除以价格变化百分比 我拥有的数据来自Zillow:“InventoryMeasure_County_Public.csv”和“City_Zhvi_AllHomes.csv” 数据位于包含时间序列数据的多索引数据帧中。它看起来是这样的,虽然有55列和290行: PQ = pd.DataFrame({ "2010q1_x":[0.1, 0.2, 0.3],
PQ = pd.DataFrame({ "2010q1_x":[0.1, 0.2, 0.3],
"2010q2_x":[0.2, 0.2, 0.2],
# ... goes to 2016q4_x
"2010q1_y":[2.1, 2.2, 2.3],
"2010q2_y":[1.2, 1.2, 1.3],
# ... goes to 2016q4_y
} index = pd.MultiIndex.from_tuples(
[('Alabama', 'Huntsville'), ('Alabama','Rainbow City')
# ... for all 50 States
('Wyoming', 'Burton County'), ('Wyoming', 'Joe Falls')],
names=['State','County'])))
我似乎一次只能做一个手术。例如:
PQ['2010q1_x'].div(PQ['2010q1_y'])
收益率:
State County
Alabama Madison -0.017560
Mobile -0.112925
Shelby -0.100689
Tuscaloosa 0.319638
Alaska Anchorage 0.261926
Juneau 0.099720
Arizona Maricopa -0.003240
Pima 0.098894
Yuma -1.982047
# ... and so on.
太完美了,这正是我需要的。我只需要对55列中的每一列执行操作,而不必编写55个表达式。
我想这样写:
(PQ['20{}q{}_x'.format([x for x in range(10,17)],[x for x in range(1,5)])])
.div(PQ['20{}q{}_y'.format([x for x in range(10,17)],[x for x in range(1,5)])])
但是,当我运行上述代码时,出现了一个关键错误:
KeyError: '20[10, 11, 12, 13, 14, 15, 16]q[1, 2, 3, 4]_x'
我发现了这些,但是,它们没有给我任何结论
我还尝试将DataFrame中的列转换为np.array,在这里我能够成功地跨两个数据进行操作,但是,当我尝试将结果添加到多索引DataFrame时,结果都是NaN
我还尝试了“取消多索引”:我将索引更改为州、县对的元组,以查看问题是否与多索引有关
希望我已经相对清楚地解释了这一点——我的最终目标非常简单,我相信我只是想得太多了
提前感谢您的帮助。我不知道是否有更多的技巧方法可以做到这一点,但这种方法可以成功
# create an empty DataFrame to store result
result = pd.DataFrame(None,
columns=pd.MultiIndex.from_tuples(list(zip(['20{}q{}_x'.format(x, y) for x in range(10,17) for y in range(1,5)],
['20{}q{}_x'.format(x, y) for x in range(10,17) for y in range(1,5)])),
names=['numerator', 'denominator']),
index=PQ.index
)
# fill the result
result = result.apply(lambda s: PQ[s.name[0]].div(PQ[s.name[1]]))
让我们使用.str.extract对列进行分组,然后进行分割 输入:
print(PQ)
2010q1_x 2010q1_y 2010q2_x 2010q2_y
State County
Alabama Huntsville 0.1 2.1 0.2 1.2
Rainbow City 0.2 2.2 0.2 1.2
Wyoming Burton County 0.3 2.3 0.2 1.3
df_out = PQ.groupby(by=PQ.columns.str.extract('(\d{4}q\d)',expand=False),axis=1).apply(lambda x: x.iloc[:,0].div(x.iloc[:,1]))
print(df_out)
输出:
2010q1 2010q2
State County
Alabama Huntsville 0.047619 0.166667
Rainbow City 0.090909 0.166667
Wyoming Burton County 0.130435 0.153846
我喜欢@Scott Boston的groupby()方法,但这里有另一种方法
import pandas as pd
PQ = pd.DataFrame({ "2010q1_x":[0.1, 0.2, 0.3],
"2010q2_x":[0.2, 0.2, 0.2],
"2010q1_y":[2.1, 2.2, 2.3],
"2010q2_y":[1.2, 1.2, 1.3]}, index = pd.MultiIndex.from_tuples(
[('Alabama', 'Huntsville'), ('Alabama','Rainbow City'),
('Wyoming', 'Burton County')],
names=['State','County']))
print (PQ)
2010q1_x 2010q1_y 2010q2_x 2010q2_y
State County
Alabama Huntsville 0.1 2.1 0.2 1.2
Rainbow City 0.2 2.2 0.2 1.2
Wyoming Burton County 0.3 2.3 0.2 1.3
使用pandasfilter
我们可以将“\x”列除以“\y”列中的值
在一些列名清理之后,它将生成
eods.columns = eods.columns.str.replace('_x','_eod')
print (eods)
2010q1_eod 2010q2_eod
State County
Alabama Huntsville 0.047619 0.166667
Rainbow City 0.090909 0.166667
Wyoming Burton County 0.130435 0.153846
这很好用!我甚至没有想到使用groupby。
eods.columns = eods.columns.str.replace('_x','_eod')
print (eods)
2010q1_eod 2010q2_eod
State County
Alabama Huntsville 0.047619 0.166667
Rainbow City 0.090909 0.166667
Wyoming Burton County 0.130435 0.153846