设置一些等于其他行pandas的行

时间:2015-12-28 22:18:59

标签: python pandas

我有一个像这样的DataFrame:

         A   B
0  name1_X   2
1  name2_X   2
2  name3_X   2
3  name1_Y NaN
4  name2_Y NaN
5  name3_Y NaN

其中A列是name,后缀为_X_Y,B列为值。

我想创建_Y等于

的行
`-1 * corresponding `_X`

具有相同的名称。

输出应为,

         A   B
0  name1_X   2
1  name2_X   2
2  name3_X   2
3  name1_Y  -2
4  name2_Y  -2
5  name3_Y  -2

有时,DataFrame将是

         A   B
0  name1_X   2
1  name1_Y NaN
2  name2_Y NaN
3  name3_Y NaN

,输出应为:

         A   B
0  name1_X   2
1  name1_Y  -2
2  name2_Y NaN
3  name3_Y NaN

非重叠部分仍为NaN

如何以简单的方式解决这个问题?

3 个答案:

答案 0 :(得分:2)

分开' X'来自数据框的值并创建相应的“Y'值。然后只是连接。

我已扩展示例数据框,以考虑名称不匹配的情况。在这种情况下,如果名称以' _X'结尾,则新的' _Y'将创建名称变量。如果有名字' _Y'但没有相应的名称' _X',那么它将保持不变。

df = pd.DataFrame({'A': ['name0_X', 'name2_X', 'name3_X', 'name1_Y', 'name2_Y', 'name4_Y'],
                   'B': [2.0, 2.0, 2.0, None, None, None]})
>>> df
         A   B
0  name0_X   2  # Create new `name0_Y`
1  name2_X   2  # Match. Multiply value by minus one.
2  name3_X   2  # Create new `name3_Y`
3  name1_Y NaN  # No match. Leave as is.
4  name2_Y NaN  # Update with matching X after multiplying by minus one.
5  name4_Y NaN  # No match. Leave as is.

dfx = df[df.A.str[-2:] == '_X']
dfy = dfx.copy()
dfy.B *= -1
dfy.A = dfy.A.str[:-2] + '_Y'
y_names = df[df.A.str[-2:] == '_Y'].A
missing_Y_names = y_names[~y_names.isin(dfy.A)]
df_missing_y = df.loc[df.A.isin(missing_Y_names), :]
result = pd.concat([dfx, dfy, df_missing_y], ignore_index=True)

>>> result
         A   B
0  name0_X   2
1  name2_X   2
2  name3_X   2
3  name0_Y  -2
4  name2_Y  -2
5  name3_Y  -2
6  name1_Y NaN
7  name4_Y NaN

答案 1 :(得分:0)

要做的第一件事是通过拆分name分隔X部分和_部分:

In [12]: df[['name', 'xy']] = df.A.str.split('_', return_type='frame')

In [13]: df
Out[13]: 
         A   B   name xy
0  name1_X   2  name1  X
1  name2_X   2  name2  X
2  name3_X   2  name3  X
3  name1_Y NaN  name1  Y
4  name2_Y NaN  name2  Y
5  name3_Y NaN  name3  Y

您现在可以使用先前在该字段name1_X中锁定的信息执行操作。

例如:

In [16]: df.set_index(['name', 'xy']).B.unstack('xy')
Out[16]: 
xy     X   Y
name        
name1  2 NaN
name2  2 NaN
name3  2 NaN

现在,您可以轻松地将Y设置为以X与您希望的方式相关联:

In [17]: df2 = df.set_index(['name', 'xy']).B.unstack('xy')

In [18]: df2.Y = df2.X * -1

In [19]: df2
Out[19]: 
xy     X  Y
name       
name1  2 -2
name2  2 -2
name3  2 -2

答案 2 :(得分:-1)

我的建议是将X数据合并到轴1上的Y数据,计算并重建。 这对我有用:

import pandas as pd
import numpy as np

df = pd.DataFrame()
df['A'] =   ['name1_X','name2_X','name3_X','name1_Y','name2_Y','name3_Y','name4_Y','name5_Y']
df['B'] = [2,2,2,np.nan,np.nan,np.nan,np.nan,np.nan]

#name column
df['name'] = [x.split('_')[0] for x in df.A]

#suffix column
df['suf'] =  [x.split('_')[1] for x in df.A]

#create y data and add same name x data
dfy = pd.merge(df[df.suf=='Y'],df[df.suf=='X'],on='name',how='left')

#preform calculation
dfy.B_x = [x*-1 for x in dfy.B_y]

#build output
output = pd.DataFrame(np.vstack([df[df.suf=='X'].values[:,:2],dfy.values[:,:2]]),columns=['A','B'])