问题描述
美好的一天,
问题:我有两个数据框-每个公司的绩效又称为每个公司的输出和输入:
`firms = ['1', '2', '3']
df = pd.DataFrame(firms)
output = { 'firms': ['1', '2', '3'],
'Sales': [150, 200, 50],
'Profit':[200, 210, 90]}
df1 = pd.DataFrame.from_dict(output)
inputs = { 'firms': ['1', '2', '3'],
'Salary': [10000, 20000, 500],
'employees':[2, 4, 5]}
df2 = pd.DataFrame.from_dict(inputs)`
我需要的是将输出表中的每一列划分为输入表中的每一列。 到目前为止,我正在以非常丑陋的方式进行操作-将整个输出tbl除以输入表中的每个单独列,然后将结果合并在一起。 当我有两列时,这一切都很好,但是我想知道是否有更好的方法,因为我可能在一个表中有100列,而在另一个表中有50列。 嗯,大小可能有所不同也很重要,例如,输入中的50 cols和输出表中的100 cols。
frst = df1.iloc[:,0:2].divide(df2.Salary, axis = 0)
frst.columns = ['y1-x1', 'y2-x1']
sec = df1.iloc[:,0:2].divide(df2.employees, axis = 0)
sec.columns = ['y1-x2', 'y2-x2']
complete = pd.DataFrame(df).join(frst).join(sec)
输出:
| 公司 y1-x1 | y2-x1 | y1-x2 | y2-x2 |
| 1 | 0.0200 | 0.015 | 100.0 | 75.0 |
| 2 | 0.0105 | 0.010 | 52.5 | 50.0 |
| 3 | 0.1800 | 0.100 | 18.0 | 10.0 |
我也尝试过使用循环,但是如果我没有记错的话,因为在我的实际示例中,我有不同大小的表,因此无法解决问题。 我将非常感谢您的建议!
1楼
因此,我认为问题在于,您实际上将数据视为三维的,具有维度(公司,成本成分,收入成分),并且您希望三个维度的每个外部乘积都具有比率。
当然,有多种方法可以完成您想要在DataFrame中完成的工作,但是它们很混乱。
熊猫确实有一个称为Panel的3-D对象,但是 ,而是希望为称为索引的高维数据结构提供更完整的解决方案。 可以将其视为NDArrays的熊猫。
我们可以通过标记和堆叠索引将您的数据转换为xarray DataArray:
In [2]: income = df1.set_index('firms').rename_axis(['income'], axis=1).stack('income').to_xarray()
In [3]: income
Out[3]:
<xarray.DataArray (firms: 3, income: 2)>
array([[150, 200],
[200, 210],
[ 50, 90]])
Coordinates:
* firms (firms) object '1' '2' '3'
* income (income) object 'Sales' 'Profit'
In [4]: costs = df2.set_index('firms').rename_axis(['costs'], axis=1).stack('costs').to_xarray()
In [5]: costs
Out[5]:
<xarray.DataArray (firms: 3, costs: 2)>
array([[10000, 2],
[20000, 4],
[ 500, 5]])
Coordinates:
* firms (firms) object '1' '2' '3'
* costs (costs) object 'Salary' 'employees'
现在,您有两个DataArray,每个DataArray具有两个维度,但是维度不匹配。
两者均由firms
索引,但收入由income
索引, costs
由costs
索引。
当对两者执行操作时,它们会自动相互 :
In [6]: income / costs
Out[6]:
<xarray.DataArray (firms: 3, income: 2, costs: 2)>
array([[[1.50e-02, 7.50e+01],
[2.00e-02, 1.00e+02]],
[[1.00e-02, 5.00e+01],
[1.05e-02, 5.25e+01]],
[[1.00e-01, 1.00e+01],
[1.80e-01, 1.80e+01]]])
Coordinates:
* firms (firms) object '1' '2' '3'
* income (income) object 'Sales' 'Profit'
* costs (costs) object 'Salary' 'employees'
现在,这些数据具有您要实现的结构,并且该划分是使用优化的cython操作而不是循环来完成的。
您可以使用内置的方法将数据转换回数据 :
In [7]: (income / costs).to_series().to_frame(name='income to cost ratio')
Out[7]:
income to cost ratio
firms income costs
1 Sales Salary 0.0150
employees 75.0000
Profit Salary 0.0200
employees 100.0000
2 Sales Salary 0.0100
employees 50.0000
Profit Salary 0.0105
employees 52.5000
3 Sales Salary 0.1000
employees 10.0000
Profit Salary 0.1800
employees 18.0000
2楼
我不明白为什么你不能只使用一个简单的循环。
似乎您想使firms
所有内容保持一致,因此将其设置为索引将解决长度不相等的所有联接或除法。
df1 = df1.set_index('firms')
df2 = df2.set_index('firms')
l = []
for col in df2.columns:
l.append(df1.div(df2[col], axis=0).add_suffix(f'_by_{col}'))
pd.concat(l, axis=1)
输出:
Sales_by_Salary Profit_by_Salary Sales_by_employees Profit_by_employees
firms
1 0.015 0.0200 75.0 100.0
2 0.010 0.0105 50.0 52.5
3 0.100 0.1800 10.0 18.0