根据三列的值有条件地交互式计算列
Conditionally and interatively calculate column based on value of three columns
我是运行Windows10,Python2.7通过SpyderIDE.
我有一个 pandas DataFrame
叫 df
:
df = pd.DataFrame({'fld1': ['x', 'x', 'x','y','y','y','z','z']
, 'fld2': ['x', 'y', 'z','x','y','z','x','y']
, 'relationship': [.25,.25,.50,.33,.33,.33,.5,.5]})
df
Out[172]:
fld1 fld2 relationship
0 x x 0.25
1 x y 0.25
2 x z 0.50
3 y x 0.33
4 y y 0.33
5 y z 0.33
6 z x 0.50
7 z y 0.50
我想构建一个 function
来迭代 Dataframe
df
的行以在 df
.
中生成一个新列
此函数将开始于:
第 1 步: 取 relationship
列,其中 fld1
= x
和 fld2
= x
然后
第 2 步: 检查 fld1
= x
的情况下是否有更多唯一值 fld2
。
第 3 步: 如果 fld2
的另一个唯一值与 fld1
= x
关联(在这两个更唯一的值中存在,x
和 y
),将 步骤 1 中的 relationship
值添加到 fld1
的 relationship
列= x
和 fld2
的下一个唯一值(在本例中 fld2
= y
是下一个唯一值)乘以关系的倒数(在本例中 fld1
= y
和 fld2
= x
)
第 4 步: 重复 第 2 步,直到 fld2
的所有唯一值与 fld1
= x
这样算出来的
步骤 4: 重复 步骤 1 以获得 fld1
的下一个唯一值。在这种情况下,它将是 fld1
= y
为了以另一种方式解释此功能逻辑,下面是在 excel
中如何完成此操作的示例:
A B C D
1 fld1 fld2 relationship Connection
2 x x 0.25 =C2+(C3*C5)+(C4*C8)
3 x y 0.25 =C3+(C4*C9)
4 x z 0.5 =C4+(C3*C7)
5 y x 0.33 =C5+(C7*C8)
6 y y 0.33 =C6+(C5*C3)+(C7*C9)
7 y z 0.33 =C7+(C5*C4)
8 z x 0.5 =C8+(C9*C5)
9 z y 0.5 =C9+(C8*C4)
该函数的输出应产生一个 Dataframe
与下面的 df2
相同的结果:
df2 = pd.DataFrame({'fld1': ['x', 'x', 'x','y','y','y','z','z']
, 'fld2': ['x', 'y', 'z','x','y','z','x','y']
, 'relationship': [.25,.25,.50,.33,.33,.33,.5,.5]
, 'connection': [.5825,0.5,0.5825,0.495,0.5775,0.495,0.665,0.75]})
df2
Out[174]:
connection fld1 fld2 relationship
0 0.5825 x x 0.25
1 0.5000 x y 0.25
2 0.5825 x z 0.50
3 0.4950 y x 0.33
4 0.5775 y y 0.33
5 0.4950 y z 0.33
6 0.6650 z x 0.50
7 0.7500 z y 0.50
好了,这就是解决您问题的一种方法。我用字典来保存每个组合的值。
xyzdict = {"xx":0.25,
"xy":0.25,
"xz":0.5,
"yx":0.33,
"yy":0.33,
"yz":0.33,
"zx":0.5,
"zy":0.5}
然后,对于每个 'connection' 组合,第一个字母始终与 fld1
的第一个字母相同。第二个字母总是 not
fld1
。因此,这是一种详尽且可能不是 pythonic 的方法来计算您的值并将组合的连接值存储在字典中供以后使用。
cnxn = {}
xyz = ["x","y","z"]
for combo in xyzdict.keys():
#print "the combo is %s" % (combo) #xyzdict[two] #actual value
first_letter = combo[0]
not_second = [combo[0],combo[1]]
not_second_letter = list(set(xyz) - set(not_second))
if len(not_second_letter) > 1:
multi_cnxn = []
for each_not_second_letter in not_second_letter:
fwd = ''.join((first_letter,each_not_second_letter))
rev = ''.join((each_not_second_letter,first_letter))
cnxnval = xyzdict[fwd] * xyzdict[rev]
multi_cnxn.append(cnxnval)
rowvalue = xyzdict[combo] + sum(multi_cnxn)
cnxn[combo] =rowvalue
else:
fwd = ''.join((first_letter,not_second_letter[0]))
rev = ''.join((not_second_letter[0],first_letter))
cnxnval = xyzdict[fwd] * xyzdict[rev]
rowvalue = xyzdict[combo] + cnxnval
cnxn[combo] = rowvalue
差不多了,定义一个函数check
,它将提取你的fld1
和fld2
和return上面cnxn
的计算值。
def check(fld1,fld2,cnxn_sub):
rowpair = ''.join((fld1,fld2))
return cnxn_sub[rowpair]
最后,pandas apply
把它全部带回家。
df['connection'] = df.apply(lambda row: check(row['fld1'], row['fld2'],cnxn), axis=1)
这是我的结果,我们的 "yz" 连接有点断,不知道是你的还是我的...
fld1 fld2 relationship connection
0 x x 0.25 0.5825
1 x y 0.25 0.5000
2 x z 0.50 0.5825
3 y x 0.33 0.4950
4 y y 0.33 0.5775
5 y z 0.33 0.4125
6 z x 0.50 0.6650
7 z y 0.50 0.7500
祝你好运!
我是运行Windows10,Python2.7通过SpyderIDE.
我有一个 pandas DataFrame
叫 df
:
df = pd.DataFrame({'fld1': ['x', 'x', 'x','y','y','y','z','z']
, 'fld2': ['x', 'y', 'z','x','y','z','x','y']
, 'relationship': [.25,.25,.50,.33,.33,.33,.5,.5]})
df
Out[172]:
fld1 fld2 relationship
0 x x 0.25
1 x y 0.25
2 x z 0.50
3 y x 0.33
4 y y 0.33
5 y z 0.33
6 z x 0.50
7 z y 0.50
我想构建一个 function
来迭代 Dataframe
df
的行以在 df
.
此函数将开始于:
第 1 步: 取 relationship
列,其中 fld1
= x
和 fld2
= x
然后
第 2 步: 检查 fld1
= x
的情况下是否有更多唯一值 fld2
。
第 3 步: 如果 fld2
的另一个唯一值与 fld1
= x
关联(在这两个更唯一的值中存在,x
和 y
),将 步骤 1 中的 relationship
值添加到 fld1
的 relationship
列= x
和 fld2
的下一个唯一值(在本例中 fld2
= y
是下一个唯一值)乘以关系的倒数(在本例中 fld1
= y
和 fld2
= x
)
第 4 步: 重复 第 2 步,直到 fld2
的所有唯一值与 fld1
= x
这样算出来的
步骤 4: 重复 步骤 1 以获得 fld1
的下一个唯一值。在这种情况下,它将是 fld1
= y
为了以另一种方式解释此功能逻辑,下面是在 excel
中如何完成此操作的示例:
A B C D
1 fld1 fld2 relationship Connection
2 x x 0.25 =C2+(C3*C5)+(C4*C8)
3 x y 0.25 =C3+(C4*C9)
4 x z 0.5 =C4+(C3*C7)
5 y x 0.33 =C5+(C7*C8)
6 y y 0.33 =C6+(C5*C3)+(C7*C9)
7 y z 0.33 =C7+(C5*C4)
8 z x 0.5 =C8+(C9*C5)
9 z y 0.5 =C9+(C8*C4)
该函数的输出应产生一个 Dataframe
与下面的 df2
相同的结果:
df2 = pd.DataFrame({'fld1': ['x', 'x', 'x','y','y','y','z','z']
, 'fld2': ['x', 'y', 'z','x','y','z','x','y']
, 'relationship': [.25,.25,.50,.33,.33,.33,.5,.5]
, 'connection': [.5825,0.5,0.5825,0.495,0.5775,0.495,0.665,0.75]})
df2
Out[174]:
connection fld1 fld2 relationship
0 0.5825 x x 0.25
1 0.5000 x y 0.25
2 0.5825 x z 0.50
3 0.4950 y x 0.33
4 0.5775 y y 0.33
5 0.4950 y z 0.33
6 0.6650 z x 0.50
7 0.7500 z y 0.50
好了,这就是解决您问题的一种方法。我用字典来保存每个组合的值。
xyzdict = {"xx":0.25,
"xy":0.25,
"xz":0.5,
"yx":0.33,
"yy":0.33,
"yz":0.33,
"zx":0.5,
"zy":0.5}
然后,对于每个 'connection' 组合,第一个字母始终与 fld1
的第一个字母相同。第二个字母总是 not
fld1
。因此,这是一种详尽且可能不是 pythonic 的方法来计算您的值并将组合的连接值存储在字典中供以后使用。
cnxn = {}
xyz = ["x","y","z"]
for combo in xyzdict.keys():
#print "the combo is %s" % (combo) #xyzdict[two] #actual value
first_letter = combo[0]
not_second = [combo[0],combo[1]]
not_second_letter = list(set(xyz) - set(not_second))
if len(not_second_letter) > 1:
multi_cnxn = []
for each_not_second_letter in not_second_letter:
fwd = ''.join((first_letter,each_not_second_letter))
rev = ''.join((each_not_second_letter,first_letter))
cnxnval = xyzdict[fwd] * xyzdict[rev]
multi_cnxn.append(cnxnval)
rowvalue = xyzdict[combo] + sum(multi_cnxn)
cnxn[combo] =rowvalue
else:
fwd = ''.join((first_letter,not_second_letter[0]))
rev = ''.join((not_second_letter[0],first_letter))
cnxnval = xyzdict[fwd] * xyzdict[rev]
rowvalue = xyzdict[combo] + cnxnval
cnxn[combo] = rowvalue
差不多了,定义一个函数check
,它将提取你的fld1
和fld2
和return上面cnxn
的计算值。
def check(fld1,fld2,cnxn_sub):
rowpair = ''.join((fld1,fld2))
return cnxn_sub[rowpair]
最后,pandas apply
把它全部带回家。
df['connection'] = df.apply(lambda row: check(row['fld1'], row['fld2'],cnxn), axis=1)
这是我的结果,我们的 "yz" 连接有点断,不知道是你的还是我的...
fld1 fld2 relationship connection
0 x x 0.25 0.5825
1 x y 0.25 0.5000
2 x z 0.50 0.5825
3 y x 0.33 0.4950
4 y y 0.33 0.5775
5 y z 0.33 0.4125
6 z x 0.50 0.6650
7 z y 0.50 0.7500
祝你好运!