将具有多列的计算结果添加到具有多索引列的DataFrame

2024-04-26 22:50:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我有这样一个数据帧:

In [10]: df.head()
Out[10]: 
      sand              silt              clay             rho_b  ...      n  \
        5     25    60    5     25    60    5     25    60    5   ...     60   
STID                                                              ...          
ACME  73.0  60.3  52.5  19.7  23.9  25.9   7.2  15.7  21.5  1.27  ...   1.32   
ADAX  61.1  51.1  47.6  22.0  25.4  24.6  16.9  23.5  27.8  1.01  ...   1.25   
ALTU  23.8  17.8  14.3  40.0  45.2  40.9  36.2  37.0  44.8  1.57  ...   1.18   
ALV2  33.3  21.2  19.8  31.4  29.7  29.8  35.3  49.1  50.5  1.66  ...   1.20   
ANT2  55.6  57.5  47.7  34.9  31.1  26.8   9.4  11.3  25.5  1.49  ...   1.29  

因此,对于每个STID(例如ACME、ADAX、ALTU),在三个深度(5、25、60)有一些属性(例如砂、粉土、粘土)。你知道吗

这种结构使得在每个STID进行每深度计算非常容易,例如:

In [12]: (df['sand'] + df['silt']).head()
Out[12]: 
        5     25    60
STID                  
ACME  92.7  84.2  78.4
ADAX  83.1  76.5  72.2
ALTU  63.8  63.0  55.2
ALV2  64.7  50.9  49.6
ANT2  90.5  88.6  74.5

如何将计算结果巧妙地合并回数据帧?例如,如果我想调用上述计算的结果'notclay'

In [13]: df['notclay'] = df['sand'] + df['silt']
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-13-a30bd9ba99c3> in <module>()
----> 1 df['notclay'] = df['sand'] + df['silt']

<snip>

ValueError: Wrong number of items passed 3, placement implies 1

结果中的每一列需要定义三列,而不仅仅是一个'notclay'列。你知道吗

我确实有一个使用严格赋值的解决方案,但我不太满意:

In [21]: df[[('notclay', 5), ('notclay', 25), ('notclay', 60)]] = df['sand'] + df['silt']

In [22]: df['notclay'].head()
Out[22]: 
        5     25    60
STID                  
ACME  92.7  84.2  78.4
ADAX  83.1  76.5  72.2
ALTU  63.8  63.0  55.2
ALV2  64.7  50.9  49.6
ANT2  90.5  88.6  74.5

我还有很多其他的计算要做,类似于这个,每次使用严格的赋值似乎很乏味。我想有一个更好的/正确的方法来做到这一点。我认为add a field in pandas dataframe with MultiIndex columns可能包含答案,但我不太了解解决方案(甚至不太了解什么是面板,它是否能帮助我)。你知道吗

编辑:我尝试了一些不起作用的东西,使用concat:

In [36]: concat([df['sand'] + df['silt']], axis=1, keys=['notclay']).head()
Out[36]: 
     notclay            
          5     25    60
STID                    
ACME    92.7  84.2  78.4
ADAX    83.1  76.5  72.2
ALTU    63.8  63.0  55.2
ALV2    64.7  50.9  49.6
ANT2    90.5  88.6  74.5

In [37]: df['notclay'] = concat([df['sand'] + df['silt']], axis=1, keys=['notclay'])
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)

<snip>

ValueError: Wrong number of items passed 3, placement implies 1

与上面提到的ValueError相同。你知道吗


Tags: indfoutheadacmevalueerrorconcatsand
1条回答
网友
1楼 · 发布于 2024-04-26 22:50:05

根据您的口味,这可能是一个更好的方法,仍然使用concat:

In [53]: df
Out[53]: 
       blah                           foo                    
          1         2         3         1         2         3
a  0.351045  0.044654  0.855627  0.839725  0.675183  0.325324
b  0.610374  0.394499  0.924708  0.924303  0.404475  0.885368
c  0.116418  0.487866  0.190669  0.283535  0.862869  0.346477
d  0.771014  0.204143  0.143449  0.848520  0.887373  0.220083
e  0.103268  0.306820  0.277125  0.627272  0.631019  0.386406

In [54]: newdf
Out[54]: 
          1         2         3
a  0.433377  0.806679  0.976298
b  0.593683  0.217415  0.086565
c  0.716244  0.908777  0.180252
d  0.031942  0.074283  0.745019
e  0.651517  0.393569  0.861616

In [56]: newdf.columns=pd.MultiIndex.from_product([['bar'], newdf.columns])

In [57]: pd.concat([df, newdf], axis=1)
Out[57]: 
       blah                           foo                           bar  \
          1         2         3         1         2         3         1   
a  0.351045  0.044654  0.855627  0.839725  0.675183  0.325324  0.433377   
b  0.610374  0.394499  0.924708  0.924303  0.404475  0.885368  0.593683   
c  0.116418  0.487866  0.190669  0.283535  0.862869  0.346477  0.716244   
d  0.771014  0.204143  0.143449  0.848520  0.887373  0.220083  0.031942   
e  0.103268  0.306820  0.277125  0.627272  0.631019  0.386406  0.651517   


          2         3  
a  0.806679  0.976298  
b  0.217415  0.086565  
c  0.908777  0.180252  
d  0.074283  0.745019  
e  0.393569  0.861616 

为了将其存储到原始数据帧中,您只需在最后一行中指定:

In [58]: df = pd.concat([df, newdf], axis=1)

相关问题 更多 >