首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >设置多级pandas数据框中的值python

设置多级pandas数据框中的值python
EN

Stack Overflow用户
提问于 2017-06-30 01:48:42
回答 1查看 512关注 0票数 1

我最近一直在使用多级DataFrames,我发现它们可以显著减少大型数据集的计算时间。例如,考虑简单的数据帧:

代码语言:javascript
复制
df = pd.DataFrame([
        [1, 111, 0], [2, 222, 0], [1, 111, 0],
        [2, 222, 1], [1, 111, 1], [2, 222, 2]
    ], columns=["ID", "A", "B"], index=[1, 1, 2, 2, 3, 3]
)
df.head(6)

    ID   A    B
1   1   111   0
1   2   222   0
2   1   111   0
2   2   222   1
3   1   111   1
3   2   222   2

它可以通过ID旋转来创建多级数据框:

代码语言:javascript
复制
pivot_df = df.pivot(columns="ID")
pivot_df.head()

     A        B
ID   1   2    1   2
1   111 222   0   0
2   111 222   0   1
3   111 222   1   2

使用这种格式的数据的好处是,我可以通过引用0级列来对所有in执行“向量”操作:

代码语言:javascript
复制
pivot_df["A"] * (1 + pivot_df["B"])**2

ID  1   2
1   111 222
2   111 888
3   444 999

这些操作对我真的很有帮助!在现实生活中,我的计算要复杂得多,需要对> 1000个ID执行。我使用的一种常见的DataFrame大小包含10列(在级别0),有1000个ID(在级别1),有350行。

我感兴趣的是要做两件事:更新这个旋转的DataFrame中特定字段的值;为这个DataFrame创建一个新列。就像这样

代码语言:javascript
复制
pivot_df["A"] = pivot_df["A"] * (1 + pivot_df["B"])**2

代码语言:javascript
复制
pivot_df["C"] = pivot_df["A"] * (1 + pivot_df["B"])**2

当我执行这两个操作时,我没有得到任何错误,但是DataFrame保持不变。我也尝试过使用.loc和.iloc,但没有成功。

我认为问题是维护计算的DataFrames的多级结构,但我对使用多级DataFrames非常陌生,不确定如何有效地解决这个问题。我有一个笨拙的变通方法,效率很低(创建一个计算DataFrames的字典,然后将它们合并在一起……

代码语言:javascript
复制
df_dict = OrderedDict()
df_dict["A"] = pivot_df["A"]
df_dict["B"] = pivot_df["B"]
df_dict["C"] = pivot_df["A"] * (1 + pivot_df["B"])**2

dfs = [val.T.set_index(np.repeat(key, val.shape[1]), append=True).T for key, val in df_dict.iteritems()]
final_df = reduce(lambda x, y: pd.merge(x, y, left_index=True, right_index=True), dfs)
final_df.columns = final_df.columns.swaplevel(0, 1)

或者类似的,

代码语言:javascript
复制
df_dict = OrderedDict()
df_dict["A"] = pivot_df["A"] * (1 + pivot_df["B"])**2
df_dict["B"] = pivot_df["B"]

dfs = [val.T.set_index(np.repeat(key, val.shape[1]), append=True).T for key, val in df_dict.iteritems()]
final_df = reduce(lambda x, y: pd.merge(x, y, left_index=True, right_index=True), dfs)
final_df.columns = final_df.columns.swaplevel(0, 1)

这不一定很笨拙(我对这个变通方法感到自豪),但这肯定不是高效或计算优化的。有人有什么建议吗?

EN

回答 1

Stack Overflow用户

发布于 2017-06-30 02:23:31

选项1

不要先旋转!

您说枢轴是很方便的,因为您可以在新的枢轴形式中执行向量计算。这是一个错误的表示,因为您可以在轴心之前轻松地执行这些计算。

代码语言:javascript
复制
df['C'] = df["A"] * (1 + df["B"]) ** 2
df.pivot(columns='ID')

      A       B       C      
ID    1    2  1  2    1     2
1   111  222  0  0  111   222
2   111  222  0  1  111   888
3   111  222  1  2  444  1998

如果您愿意,也可以使用管道一行程序

代码语言:javascript
复制
df.assign(C=df.A * (1 + df.B) ** 2).pivot(columns='ID')

      A       B       C      
ID    1    2  1  2    1     2
1   111  222  0  0  111   222
2   111  222  0  1  111   888
3   111  222  1  2  444  1998

选项2

pd.concat

但是为了回答你的问题..。

代码语言:javascript
复制
pdf = df.pivot(columns='ID')
pd.concat([
        pdf.A, pdf.B, pdf.A * (1 + pdf.B) ** 2
    ], axis=1, keys=['A', 'B', 'C'])

      A       B       C      
ID    1    2  1  2    1     2
1   111  222  0  0  111   222
2   111  222  0  1  111   888
3   111  222  1  2  444  1998

选项3

更多pd.concat

在合并之前将另一个标高添加到列

代码语言:javascript
复制
pdf = df.pivot(columns='ID')
c = pdf.A * (1 + pdf.B) ** 2
c.columns = [['C'] * len(c.columns), c.columns]

pd.concat([pdf, c], axis=1)

      A       B       C      
ID    1    2  1  2    1     2
1   111  222  0  0  111   222
2   111  222  0  1  111   888
3   111  222  1  2  444  1998
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44831861

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档