首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >熊猫DataFrame计算

熊猫DataFrame计算
EN

Stack Overflow用户
提问于 2015-04-17 23:38:10
回答 2查看 2.2K关注 0票数 2

我有一个相当复杂的dataframe,如下所示:

代码语言:javascript
复制
df = pd.DataFrame({'0': {('Total Number of End Points', '0.01um', '0hr'): 12,
  ('Total Number of End Points', '0.1um', '0hr'): 8,
  ('Total Number of End Points', 'Control', '0hr'): 4,
  ('Total Number of End Points', '0.01um', '24hr'): 18,
  ('Total Number of End Points', '0.1um', '24hr'): 12,
  ('Total Number of End Points', 'Control', '24hr'): 6,
  ('Total Vessel Length', '0.01um', '0hr'): 12,
  ('Total Vessel Length', '0.1um', '0hr'): 8,
  ('Total Vessel Length', 'Control', '0hr'): 4,
  ('Total Vessel Length', '0.01um', '24hr'): 18,
  ('Total Vessel Length', '0.1um',  '24hr'): 12,
  ('Total Vessel Length', 'Control',  '24hr'): 6},
  '1': {('Total Number of End Points', '0.01um', '0hr'): 12,
  ('Total Number of End Points', '0.1um', '0hr'): 8,
  ('Total Number of End Points', 'Control', '0hr'): 4,
  ('Total Number of End Points', '0.01um', '24hr'): 18,
  ('Total Number of End Points', '0.1um', '24hr'): 12,
  ('Total Number of End Points', 'Control', '24hr'): 6,
  ('Total Vessel Length', '0.01um', '0hr'): 12,
  ('Total Vessel Length', '0.1um', '0hr'): 8,
  ('Total Vessel Length', 'Control', '0hr'): 4,
  ('Total Vessel Length', '0.01um', '24hr'): 18,
  ('Total Vessel Length', '0.1um',  '24hr'): 12,
  ('Total Vessel Length', 'Control',  '24hr'): 6},
  '2': {('Total Number of End Points', '0.01um', '0hr'): 12,
  ('Total Number of End Points', '0.1um', '0hr'): 8,
  ('Total Number of End Points', 'Control', '0hr'): 4,
  ('Total Number of End Points', '0.01um', '24hr'): 18,
  ('Total Number of End Points', '0.1um', '24hr'): 12,
  ('Total Number of End Points', 'Control', '24hr'): 6,
  ('Total Vessel Length', '0.01um', '0hr'): 12,
  ('Total Vessel Length', '0.1um', '0hr'): 8,
  ('Total Vessel Length', 'Control', '0hr'): 4,
  ('Total Vessel Length', '0.01um', '24hr'): 18,
  ('Total Vessel Length', '0.1um',  '24hr'): 12,
  ('Total Vessel Length', 'Control',  '24hr'): 6}})

print(df)
                                                 0   1   2
        Total Number of End Points 0.01um  0hr   12  12  12
                                           24hr  18  18  18
                                   0.1um   0hr    8   8   8
                                           24hr  12  12  12
                                   Control 0hr    4   4   4
                                           24hr   6   6   6
        Total Vessel Length        0.01um  0hr   12  12  12
                                           24hr  18  18  18
                                   0.1um   0hr    8   8   8
                                           24hr  12  12  12
                                   Control 0hr    4   4   4
                                           24hr   6   6   6

我试图将每个值除以相应控制级别中列的平均值。我试过以下几种方法,但都没有用。

代码语言:javascript
复制
df2 = df.divide(df.xs('Control', level=1).mean(axis=1), axis='index')

我对python和大熊猫非常陌生,所以我倾向于用MS的术语来思考这个问题。

如果在Excel中,A1的公式(“端点总数”、“0.01um”、“0HR”、“0)”看起来如下:

=A1 / AVERAGE($A$5:$C$5)

B1 (“端点总数”、“0.01um”、“0HR”,1)将是:

=B1 / AVERAGE($A$5:$C$5)

A2 (“端点总数”、“0.01um”、“24小时”、“0”)为

=A1 / AVERAGE($A$6:$C$6)

本例的预期结果是:

代码语言:javascript
复制
                                                 0  1  2
        Total Number of End Points 0.01um  0hr   3  3  3
                                           24hr  3  3  3
                                   0.1um   0hr   2  2  2
                                           24hr  2  2  2
                                   Control 0hr   1  1  1
                                           24hr  1  1  1
        Total Vessel Length        0.01um  0hr   3  3  3
                                           24hr  3  3  3
                                   0.1um   0hr   2  2  2
                                           24hr  2  2  2
                                   Control 0hr   1  1  1
                                           24hr  1  1  1

注意:实际数据中有许多索引和列。

EN

回答 2

Stack Overflow用户

发布于 2015-04-18 01:27:12

在它们自己的列中包含Control值是很有帮助的。您可以使用unstack来实现这一点。

代码语言:javascript
复制
df.index.names = ['field', 'type', 'time']
df2 = df.unstack(['type']).swaplevel(0, 1, axis=1)

# type                            0.01um 0.1um Control 0.01um 0.1um Control  \
#                                      0     0       0      1     1       1   
# field                      time                                             
# Total Number of End Points 0hr      12     8       4     12     8       4   
#                            24hr     18    12       6     18    12       6   
# Total Vessel Length        0hr      12     8       4     12     8       4   
#                            24hr     18    12       6     18    12       6   

# type                            0.01um 0.1um Control  
#                                      2     2       2  
# field                      time                       
# Total Number of End Points 0hr      12     8       4  
#                            24hr     18    12       6  
# Total Vessel Length        0hr      12     8       4  
#                            24hr     18    12       6  

现在查找每个控件的平均值:

代码语言:javascript
复制
ave = df2['Control'].mean(axis=1)
# field                       time
# Total Number of End Points  0hr     4
#                             24hr    6
# Total Vessel Length         0hr     4
#                             24hr    6
# dtype: float64

正如您所期望的,您可以使用df2.divide来计算所需的结果。确保使用axis=0根据行索引告诉Pandas匹配值(在df2ave中)。

代码语言:javascript
复制
result = df2.divide(ave, axis=0)
# type                            0.01um 0.1um Control 0.01um 0.1um Control  \
#                                      0     0       0      1     1       1   
# field                      time                                             
# Total Number of End Points 0hr       3     2       1      3     2       1   
#                            24hr      3     2       1      3     2       1   
# Total Vessel Length        0hr       3     2       1      3     2       1   
#                            24hr      3     2       1      3     2       1   

# type                            0.01um 0.1um Control  
#                                      2     2       2  
# field                      time                       
# Total Number of End Points 0hr       3     2       1  
#                            24hr      3     2       1  
# Total Vessel Length        0hr       3     2       1  
#                            24hr      3     2       1  

本质上有你所追求的价值。但是,如果您想重新排列DataFrame以使其看起来与您发布的完全相同,那么:

代码语言:javascript
复制
result = result.stack(['type'])
result = result.reorder_levels(['field','type','time'], axis=0)
result = result.reindex(df.index)

收益率

代码语言:javascript
复制
                                         0  1  2
field                      type    time         
Total Number of End Points 0.01um  0hr   3  3  3
                                   24hr  3  3  3
                           0.1um   0hr   2  2  2
                                   24hr  2  2  2
                           Control 0hr   1  1  1
                                   24hr  1  1  1
Total Vessel Length        0.01um  0hr   3  3  3
                                   24hr  3  3  3
                           0.1um   0hr   2  2  2
                                   24hr  2  2  2
                           Control 0hr   1  1  1
                                   24hr  1  1  1

把这一切结合在一起:

代码语言:javascript
复制
df.index.names = ['field', 'type', 'time']
df2 = df.unstack(['type']).swaplevel(0, 1, axis=1)
ave = df2['Control'].mean(axis=1)
result = df2.divide(ave, axis=0)
result = result.stack(['type'])
result = result.reorder_levels(['field','type','time'], axis=0)
result = result.reindex(df.index)
票数 1
EN

Stack Overflow用户

发布于 2015-04-18 00:49:33

这里的问题是熊猫组织起来很容易计算列,这个问题需要从其他行中扣除一行的平均值。熊猫不是为了那样工作而设计的。

但是,您可以使用转置.T轻松地切换行和列,然后它可能更容易处理,实际上控制方式是一个一行。

代码语言:javascript
复制
>>> df.T[(u'Total Vessel Length', u'Control', u'0hr')].mean()
4.0

此4.0来自原始数据中的两个4.0值:

代码语言:javascript
复制
>>> df.T[(u'Total Vessel Length', u'Control', u'0hr')]
a    4
b    4

此时,for循环将处理这个问题。

未经测试:

代码语言:javascript
复制
for primary in (u'Total Vessel Length',u'Total Number of End Points'):
     for um in (u'0.01um',u'0.1um'):
         for hours in (u'0hr',u'24hr'):
             df.T[(primary,um,hours)]=df.T[(primary,um,hours)]/df.T[(primary, u'Control', hours)].mean()

请注意,这并没有划分非控制列,但是在um循环中包含“control”是很容易的。

UPDATE不工作,不知怎么的,它没有修改数据格式。现在,我不知道为什么。

但是,您可以通过对dict理解调用pd.DataFrame来构造一个新的数据框架。

这看起来很管用..。

代码语言:javascript
复制
import pandas as pd

df = pd.DataFrame({'0': {('Total Number of End Points', '0.01um', '0hr'): 12,
  ('Total Number of End Points', '0.1um', '0hr'): 8,
  ('Total Number of End Points', 'Control', '0hr'): 4,
  ('Total Number of End Points', '0.01um', '24hr'): 18,
  ('Total Number of End Points', '0.1um', '24hr'): 12,
  ('Total Number of End Points', 'Control', '24hr'): 6,
  ('Total Vessel Length', '0.01um', '0hr'): 12,
  ('Total Vessel Length', '0.1um', '0hr'): 8,
  ('Total Vessel Length', 'Control', '0hr'): 4,
  ('Total Vessel Length', '0.01um', '24hr'): 18,
  ('Total Vessel Length', '0.1um',  '24hr'): 12,
  ('Total Vessel Length', 'Control',  '24hr'): 6},
  '1': {('Total Number of End Points', '0.01um', '0hr'): 12,
  ('Total Number of End Points', '0.1um', '0hr'): 8,
  ('Total Number of End Points', 'Control', '0hr'): 4,
  ('Total Number of End Points', '0.01um', '24hr'): 18,
  ('Total Number of End Points', '0.1um', '24hr'): 12,
  ('Total Number of End Points', 'Control', '24hr'): 6,
  ('Total Vessel Length', '0.01um', '0hr'): 12,
  ('Total Vessel Length', '0.1um', '0hr'): 8,
  ('Total Vessel Length', 'Control', '0hr'): 4,
  ('Total Vessel Length', '0.01um', '24hr'): 18,
  ('Total Vessel Length', '0.1um',  '24hr'): 12,
  ('Total Vessel Length', 'Control',  '24hr'): 6},
  '2': {('Total Number of End Points', '0.01um', '0hr'): 12,
  ('Total Number of End Points', '0.1um', '0hr'): 8,
  ('Total Number of End Points', 'Control', '0hr'): 4,
  ('Total Number of End Points', '0.01um', '24hr'): 18,
  ('Total Number of End Points', '0.1um', '24hr'): 12,
  ('Total Number of End Points', 'Control', '24hr'): 6,
  ('Total Vessel Length', '0.01um', '0hr'): 12,
  ('Total Vessel Length', '0.1um', '0hr'): 8,
  ('Total Vessel Length', 'Control', '0hr'): 4,
  ('Total Vessel Length', '0.01um', '24hr'): 18,
  ('Total Vessel Length', '0.1um',  '24hr'): 12,
  ('Total Vessel Length', 'Control',  '24hr'): 6}})

print df

df2 = pd.DataFrame({(primary,um,hours):df.T[(primary,um,hours)]/df.T[(primary,u'Control',hours)].mean() for primary in (u'Total Vessel Length',u'Total Number of End Points') for um in (u'0.01um',u'0.1um') for hours in (u'0hr',u'24hr')})

print df2.T

输出

代码语言:javascript
复制
paul@home:~/SO$ python ./r.py 
                                              0   1   2
(Total Number of End Points, 0.01um, 0hr)    12  12  12
(Total Number of End Points, 0.01um, 24hr)   18  18  18
(Total Number of End Points, 0.1um, 0hr)      8   8   8
(Total Number of End Points, 0.1um, 24hr)    12  12  12
(Total Number of End Points, Control, 0hr)    4   4   4
(Total Number of End Points, Control, 24hr)   6   6   6
(Total Vessel Length, 0.01um, 0hr)           12  12  12
(Total Vessel Length, 0.01um, 24hr)          18  18  18
(Total Vessel Length, 0.1um, 0hr)             8   8   8
(Total Vessel Length, 0.1um, 24hr)           12  12  12
(Total Vessel Length, Control, 0hr)           4   4   4
(Total Vessel Length, Control, 24hr)          6   6   6

[12 rows x 3 columns]
                                            0  1  2
(Total Number of End Points, 0.01um, 0hr)   3  3  3
(Total Number of End Points, 0.01um, 24hr)  3  3  3
(Total Number of End Points, 0.1um, 0hr)    2  2  2
(Total Number of End Points, 0.1um, 24hr)   2  2  2
(Total Vessel Length, 0.01um, 0hr)          3  3  3
(Total Vessel Length, 0.01um, 24hr)         3  3  3
(Total Vessel Length, 0.1um, 0hr)           2  2  2
(Total Vessel Length, 0.1um, 24hr)          2  2  2

[8 rows x 3 columns]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29711130

复制
相关文章

相似问题

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