【问题标题】:Pandas division with 2 dfs带有 2 个 dfs 的熊猫师
【发布时间】:2018-05-08 07:55:29
【问题描述】:

我想通过匹配他们的名字来划分 2 个 dfs。例如,

df1 = pd.DataFrame({'Name':['xy-yz','xa-ab','yz-ijk','zb-ijk'],1:[1,2,3,4],2:[1,2,1,2],3:[2,2,2,2]} )

df2 = pd.DataFrame({'Name2':['x','y','z','a'],1:[0,1,2,3],2:[1,2,3,4],3:[5,5,5,6]})

df1:

Name1    1   2   3
xy-yz    1   1   2
xa-ab    2   2   2
yz-ijk   3   1   2
zb-ijk   4   2   2

df2:

Name2   1   2   3
x       0   1   5
y       1   2   5
z       2   3   5
a       3   4   6

结果将是 df3:

Name1    1   2   3
xy-yz    1   1   2
x        0   1   5
xy-yz        1   .4   <---(xy-yz)/x   
xa-ab    2   2   2
x        0   1   5
xa-ab        2   .4    <---(xa-ab)/x
yz-ijk   3   1   2
y        1   2   5
yz-ijk   3   .5  .4    <---(yz-ijk)/y
zb-ijk   4   2   2
z        2   3   5
zb-ijk   2   .67 .4    <---(zb-ijk)/z

我会使用 concat 但我不确定如何通过将 Name2 映射到 Name1 中的第一个字母来进行除法。

谢谢!

【问题讨论】:

  • 执行除法很容易。挑战在于你有这种奇怪的输出表示;-)
  • @cᴏʟᴅsᴘᴇᴇᴅ 它不必是那种格式。我会在那里使用 concat(df1,df2,division) 。我是这样安排的,这样每个人都更容易理解其中的逻辑。

标签: python pandas dataframe division


【解决方案1】:

我不知道你为什么需要它,但这回馈你需要的东西

df2=df2.set_index('Name2')
dfNew=df2.reindex(df1.Name1.str.split('-',expand=True)[0])
df1=df1.set_index('Name1')
pd.concat([df1.reset_index(),dfNew.reset_index().rename(columns={0:'Name1'}),pd.DataFrame(df1.values/dfNew.values,columns=df1.columns).assign(Name1=df1.index)]).sort_index()


Out[897]: 
          1         2    3  Name1
0  1.000000  1.000000  2.0   x-yz
0  0.000000  1.000000  5.0      x
0       inf  1.000000  0.4   x-yz
1  2.000000  2.000000  2.0   x-ab
1  0.000000  1.000000  5.0      x
1       inf  2.000000  0.4   x-ab
2  3.000000  1.000000  2.0  y-ijk
2  1.000000  2.000000  5.0      y
2  3.000000  0.500000  0.4  y-ijk
3  4.000000  2.000000  2.0  z-ijk
3  2.000000  3.000000  5.0      z
3  2.000000  0.666667  0.4  z-ijk

【讨论】:

  • 不知道为什么这会给我错误:操作数无法与形状一起广播 (4,10) (4,9)
  • @TylerNG 抱歉更新,忘记添加 df1=df1.set_index('Name1')
【解决方案2】:

设置 -

df1 = df1.set_index('Name')
df2 = df2.set_index('Name2')
df1

        1  2  3
Name           
xy-yz   1  1  2
xa-ab   2  2  2
yz-ijk  3  1  2
zb-ijk  4  2  2

df2

       1  2  3
Name2         
x      0  1  5
y      1  2  5
z      2  3  5
a      3  4  6

根据df1 的首字母从df2 中检索相关行。

i = df2.loc[df1.index.str[0]]
i

       1  2  3
Name2         
x      0  1  5
x      0  1  5
y      1  2  5
z      2  3  5

执行除法并重置索引。

j = (df1.set_index(i.index) / i).set_index(df1.index)
j
               1         2    3
Name                           
xy-yz        inf  1.000000  0.4
xa-ab        inf  2.000000  0.4
yz-ijk  3.000000  0.500000  0.4
zb-ijk  2.000000  0.666667  0.4

连接结果。

pd.concat([df1, i, j])

               1         2    3
xy-yz   1.000000  1.000000  2.0
xa-ab   2.000000  2.000000  2.0
yz-ijk  3.000000  1.000000  2.0
zb-ijk  4.000000  2.000000  2.0
x       0.000000  1.000000  5.0
x       0.000000  1.000000  5.0
y       1.000000  2.000000  5.0
z       2.000000  3.000000  5.0
xy-yz        inf  1.000000  0.4
xa-ab        inf  2.000000  0.4
yz-ijk  3.000000  0.500000  0.4
zb-ijk  2.000000  0.666667  0.4

如果你想屏蔽非实数值,再一次在j 上使用np.isfinite -

j  = j[np.isfinite(j)].fillna('')
j

        1         2    3
Name                    
xy-yz      1.000000  0.4
xa-ab      2.000000  0.4
yz-ijk  3  0.500000  0.4
zb-ijk  2  0.666667  0.4

之后使用 this j 作为连接的参数。

【讨论】:

  • 只是一些小的调整,而不是 df1.index.str[0] ,我们可以搜索到“ - ”吗?例如,对于 xyz - abc,如果我们使用 df1.index.str[0] 我们将得到 x,我们如何获得完整的 zyz?
  • @TylerNG df1.index.str.split('-').str[0]?
  • @TylerNG 好的,我想其中一个语句应该改为df2.loc[df1.index.str.split('-').str[0].str.strip()]
  • @TylerNG 另外,请记住,更改数据/问题会使答案无效,所以尽量不要太频繁:-)
  • 哎呀我不知道。我试过 i = df2.loc[df1.index.str.split('-').str[0]] 但我一直收到“None of [Index(['1', '2', '2' ... dtype='object', name='Label')] 在 [index]" 中。让我根据我的实际数据进行调整。
猜你喜欢
  • 2018-06-05
  • 2018-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-06
  • 1970-01-01
  • 1970-01-01
  • 2018-10-20
相关资源
最近更新 更多