我正在尝试创建一个矩阵来显示Pandas数据框中行之间的差异。
import pandas as pd
data = {'Country':['GB','JP','US'],'Values':[20.2,-10.5,5.7]}
df = pd.DataFrame(data)
我想这样:
Country Values
0 GB 20.2
1 JP -10.5
2 US 5.7
成为这样的东西(差异垂直):
Country GB JP US
0 GB 0.0 -30.7 14.5
1 JP 30.7 0.0 16.2
2 US 14.5 -16.2 0.0
这可以通过内置函数实现,还是需要构建一个循环来获得所需的输出?谢谢你的帮助!
答案 0 :(得分:7)
这是numpy' broadcasting的标准用例:
df['Values'].values - df['Values'].values[:, None]
Out:
array([[ 0. , -30.7, -14.5],
[ 30.7, 0. , 16.2],
[ 14.5, -16.2, 0. ]])
我们使用values属性访问底层numpy数组,[:, None]
引入一个新轴,因此结果是二维的。
您可以将其与原始系列相结合:
arr = df['Values'].values - df['Values'].values[:, None]
pd.concat((df['Country'], pd.DataFrame(arr, columns=df['Country'])), axis=1)
Out:
Country GB JP US
0 GB 0.0 -30.7 -14.5
1 JP 30.7 0.0 16.2
2 US 14.5 -16.2 0.0
由于@Divakar:
,也可以使用以下代码生成数组arr = np.subtract.outer(*[df.Values]*2).T
我们在subtract
ufunc上调用.outer
,并将其应用于所有输入对。
答案 1 :(得分:2)
我尝试改进Divakar
评论:
cars GET /transportation(.:format) cars#index
POST /transportation(.:format) cars#create
new_car GET /transportation/new(.:format) cars#new
edit_car GET /transportation/:id/edit(.:format) cars#edit
car GET /transportation/:id(.:format) cars#show
PATCH /transportation/:id(.:format) cars#update
PUT /transportation/:id(.:format) cars#update
DELETE /transportation/:id(.:format) cars#destroy
答案 2 :(得分:0)
选项1
from itertools import product
import pandas as pd
DF=pd.DataFrame(list(product(df.Country, df.Country)), columns=['l1', 'l2'])
df=df.set_index('Country')
DF['v1']=DF.l1.map(df['Values'])
DF['v2']=DF.l2.map(df['Values'])
DF['DIFF']=DF['v2']-DF['v1']
DF.pivot(index='l1', columns='l2', values='DIFF').fillna(0).rename_axis(None).rename_axis(None,1)
Out[94]:
GB JP US
GB 0.0 -30.7 -14.5
JP 30.7 0.0 16.2
US 14.5 -16.2 0.0
选项2
使用apply
A=df['Values'].apply(lambda x : df['Values']-x)
A.columns=df.Country
A['Country']=df.Country
A
Out[124]:
Country GB JP US Country
0 0.0 -30.7 -14.5 GB
1 30.7 0.0 16.2 JP
2 14.5 -16.2 0.0 US