过去几周我一直试图构建一个回归输出的数据框,而且我已经完成了大部分工作。我现在正试图围绕列中的某些关键字对其进行重新整理,据我所知,该列不可调用。
我的数据框的简化版本如下:
? coef pval se rsq
Intercept 1 0 .1 .1
Cash 2 0.2 .05 .1
Food 2 0.05 .2 .1
Intercept 3 0 .1 .2
Cash 1 0.01 .2 .2
Food 2 0.3 .1 .2
Zone 1 0.4 .3 .2
我想要实现的目标是:
(1) (2)
Intercept coef 1 3
Intercept pval 0 0
Intercept se 0.1 0.1
Cash coef 2 1
Cash pval 0.2 0.01
Cash se 0.05 0.2
Food coef 2 2
Food pval 0.05 0.3
Food se 0.2 0.1
Zone coef NaN 1
Zone pval NaN 0.4
Zone se NaN 0.3
rsq 0.1 0.2
到目前为止,我已经尝试了几种方法,有希望的是使用r-squared(rsq)作为索引进行重新整形 - > RegTable = RegTable.pivot(index='rsq', columns=['pval', 'coef', 'robust_se'])
然而,这会返回错误ValueError: all arrays must be same length
。一些研究让我觉得这是因为截至目前,zone = NaN
由回归表示,根本没有区域行,但我不确定如何解决它。另外,我一直无法弄清楚如何调用我标识为#34;?"的列。使用PANDAS - 它没有在CSV输出中标记。此外,这种方法似乎有问题,因为两次回归具有相同的r平方的概率,它将最终抛出新的错误或平均每个值,这两者都不是完全合乎需要的。
答案 0 :(得分:3)
让我们试试这个:
df.set_index(['rsq','?']).stack().unstack([0]).T\
.reset_index().T.rename_axis([None,None])\
.rename(columns={0:'(1)',1:'(2)'})\
.sort_index()
df:
? coef pval se rsq
0 Intercept 1 0.00 0.10 0.1
1 Cash 2 0.20 0.05 0.1
2 Food 2 0.05 0.20 0.1
3 Intercept 3 0.00 0.10 0.2
4 Cash 1 0.01 0.20 0.2
5 Food 2 0.30 0.10 0.2
6 Zone 1 0.40 0.30 0.2
输出:
(1) (2)
Cash coef 2.00 1.00
pval 0.20 0.01
se 0.05 0.20
Food coef 2.00 2.00
pval 0.05 0.30
se 0.20 0.10
Intercept coef 1.00 3.00
pval 0.00 0.00
se 0.10 0.10
Zone coef NaN 1.00
pval NaN 0.40
se NaN 0.30
rsq 0.10 0.20
答案 1 :(得分:2)
这种解决方案背后的直觉是将数据帧分成两个大致相等的部分。这里的假设是你只有两组数据点,所以这变得易于管理。
print(df)
coef pval se rsq
Intercept 1 0.00 0.10 0.1
Cash 2 0.20 0.05 0.1
Food 2 0.05 0.20 0.1
Intercept 3 0.00 0.10 0.2
Cash 1 0.01 0.20 0.2
Food 2 0.30 0.10 0.2
Zone 1 0.40 0.30 0.2
df_ = df.reset_index().iloc[:, :-1]
df2 = df_.iloc[df_['index'].drop_duplicates(keep='first').to_frame().index]
df1 = df_.iloc[df_['index'].drop_duplicates(keep='last')\
.to_frame().index.difference(df2.index)]
完成后,每件必须堆叠,然后沿第一轴连接。
out = pd.concat([df1.set_index('index').stack(),\
df2.set_index('index').stack()], 1)
out.append(pd.DataFrame([df.rsq.unique()], index=[('rsq', '')]))
out.columns = ['1', '2']
print(out)
1 2
index
Cash coef 1.00 2.00
pval 0.01 0.20
se 0.20 0.05
Food coef 2.00 2.00
pval 0.30 0.05
se 0.10 0.20
Intercept coef 3.00 1.00
pval 0.00 0.00
se 0.10 0.10
Zone coef NaN 1.00
pval NaN 0.40
se NaN 0.30
rsq 0.10 0.20
答案 2 :(得分:1)
这里有一个稍微偏心的方法,可以不分成两个数据帧。
此解决方案重命名索引以跟踪它们所属的回归,并在NaN
时添加缺少的字段(如Zone
的情况)。
然后groupby
,stack
,并将列表列拆分为(1)
和(2)
列(尽管它已被广义化以处理与数据中出现的一样多的回归)。
df
为:
coef pval se rsq
Intercept 1 0 .1 .1
Cash 2 0.2 .05 .1
Food 2 0.05 .2 .1
Intercept 3 0 .1 .2
Cash 1 0.01 .2 .2
Food 2 0.3 .1 .2
Zone 1 0.4 .3 .2
将索引值重命名为Intercept0
,Intercept1
等:
measures = df.index.unique()
found = {m:0 for m in measures}
for i, name in enumerate(df.index):
if np.max(list(found.values())) > found[name]+1:
df.loc["{}{}".format(name, found[name])] = np.nan
found[name] += 1
df.index.values[i] = "{}{}".format(name, found[name])
found[name] += 1
df
coef pval se rsq
Intercept0 1.0 0.00 0.10 0.1
Cash0 2.0 0.20 0.05 0.1
Food0 2.0 0.05 0.20 0.1
Intercept1 3.0 0.00 0.10 0.2
Cash1 1.0 0.01 0.20 0.2
Food1 2.0 0.30 0.10 0.2
Zone1 1.0 0.40 0.30 0.2
Zone0 NaN NaN NaN NaN
现在排列行,以便将每个回归中的元素组合在一起。 (这主要是为了在正确的位置获取NaN
行。)
order_by_reg = sorted(df.index, key=lambda x: ''.join(reversed(x)))
df = df.loc[order_by_reg]
df
coef pval se rsq
Food0 2.0 0.05 0.20 0.1
Zone0 NaN NaN NaN NaN
Cash0 2.0 0.20 0.05 0.1
Intercept0 1.0 0.00 0.10 0.1
Food1 2.0 0.30 0.10 0.2
Zone1 1.0 0.40 0.30 0.2
Cash1 1.0 0.01 0.20 0.2
Intercept1 3.0 0.00 0.10 0.2
最后,groupby
,stack
,并将结果列的列分割为apply(pd.Series)
:
gb = (df.groupby(lambda x: x[:-1])
.agg(lambda x: list(x))
.stack()
.apply(lambda pair: pd.Series({"({})".format(i):el for i, el in enumerate(pair)})))
gb
(0) (1)
Cash coef 2.00 1.00
pval 0.20 0.01
se 0.05 0.20
rsq 0.10 0.20
Food coef 2.00 2.00
pval 0.05 0.30
se 0.20 0.10
rsq 0.10 0.20
Intercept coef 1.00 3.00
pval 0.00 0.00
se 0.10 0.10
rsq 0.10 0.20
Zone coef NaN 1.00
pval NaN 0.40
se NaN 0.30
rsq NaN 0.20