在 python 数据框中划分几列,其中分子和分母列将根据选择列表而变化

Divide several columns in a python dataframe where the both the numerator and denominator columns will vary based on a picklist

我根据最终用户在选择列表中所做的选择,通过配对一个非常大的数据框(大约 400 列)来创建一个数据框。选择列表的选择之一是最终用户想要的分母类型。这是一个示例 table,其中包含进行最终计算之前的所有信息。

                county  _tcount  _tvote  _f_npb_18_count  _f_npb_18_vote  
countycode                                                                     
35              San Benito    28194   22335             2677            1741   
36          San Bernardino   912653  661838           108724           61832



countycode            _f_npb_30_count  _f_npb_30_vote                                  
35                      384             288  
36                    76749           53013

但是,我无法创建自动将从第 5 列开始的每一列(不包括索引)除以它之前的列(跳过所有其他列)的代码。我看过示例 (),但它们都使用固定的列名,这在这方面是无法实现的。我能够通过固定列改变列(基于位置),但不能通过基于位置的其他可变列改变列。我尝试根据列位置修改上面 link 中的代码:

calculated_frame = [county_select_frame[county_select_frame.columns[5: : 2]].div(county_select_frame[4: :2], axis=0)]

输出:

[           county  _tcount  _tvote  _f_npb_18_count  _f_npb_18_vote  \
countycode                                                         
35            NaN      NaN     NaN              NaN             NaN
36            NaN      NaN     NaN              NaN             NaN]

RuntimeWarning: invalid value encountered in greater (abs_vals > 0)).any()

当股息固定时,[5: :2] 的使用确实有效 field.If 我无法让它工作,这没什么大不了的(但如果有所有选项会很棒我想要)。

我认为您可以除以 values 创建的 numpy array,因为那样不会对齐列名。最后通过构造函数创建新的 DataFrame

arr = county_select_frame.values
df1 = pd.DataFrame(arr[:,5::2] / arr[:,4::2], columns = county_select_frame.columns[5::2])

样本:

np.random.seed(10)
county_select_frame = pd.DataFrame(np.random.randint(10, size=(10,10)),
                                   columns=list('abcdefghij'))
print (county_select_frame)
   a  b  c  d  e  f  g  h  i  j
0  9  4  0  1  9  0  1  8  9  0
1  8  6  4  3  0  4  6  8  1  8
2  4  1  3  6  5  3  9  6  9  1
3  9  4  2  6  7  8  8  9  2  0
4  6  7  8  1  7  1  4  0  8  5
5  4  7  8  8  2  6  2  8  8  6
6  6  5  6  0  0  6  9  1  8  9
7  1  2  8  9  9  5  0  2  7  3
8  0  4  2  0  3  3  1  2  5  9
9  0  1  0  1  9  0  9  2  1  1

arr = county_select_frame.values
df1 = pd.DataFrame(arr[:,5::2] / arr[:,4::2], columns = county_select_frame.columns[5::2])
print (df1)
          f         h         j
0  0.000000  8.000000  0.000000
1       inf  1.333333  8.000000
2  0.600000  0.666667  0.111111
3  1.142857  1.125000  0.000000
4  0.142857  0.000000  0.625000
5  3.000000  4.000000  0.750000
6       inf  0.111111  1.125000
7  0.555556       inf  0.428571
8  1.000000  2.000000  1.800000
9  0.000000  0.222222  1.000000

怎么样

cols = my_df.columns
for i in range(2, 6):
    print(u'Creating new col %s', cols[i])
    my_df['new_{0}'.format(cols[i]) = my_df[cols[i]] / my_df[cols[i-1] 

我的偏好是通过设置索引并使用 filter 分别拆分计数和投票数据帧来组织它。然后使用 join

d1 = df.set_index('county', append=True)
counts = d1.filter(regex='.*_\d+_count$').rename(columns=lambda x: x.replace('_count', ''))
votes = d1.filter(regex='.*_\d+_vote$').rename(columns=lambda x: x.replace('_vote', ''))

d1[['_tcount', '_tvote']].join(votes / counts)

                           _tcount  _tvote  _f_npb_18  _f_npb_30
countycode county                                               
35         San Benito        28194   22335   0.650355   0.750000
36         San Bernardino   912653  661838   0.568706   0.690732