根据三列的值有条件地和交互地计算列
Posted
技术标签:
【中文标题】根据三列的值有条件地和交互地计算列【英文标题】:Conditionally and interatively calculate column based on value of three columns 【发布时间】:2016-04-20 08:16:00 【问题描述】:我正在通过 Spyder IDE 运行 Windows 10、Python 2.7。
我有一只熊猫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
),将 Step 1 中的 relationship
值添加到 fld1
= x
的 relationship
列和 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)
函数的输出应该产生一个与下面的df2
相同的Dataframe
:
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
【问题讨论】:
【参考方案1】:好的,这是解决问题的一种方法。我使用字典来保存每个组合的值。
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
然后,对于每个“连接”组合,第一个字母始终与 fld1
的第一个字母相同。第二个字母总是not
fld1
。因此,这里有一种详尽且可能不是 Python 的方法来计算您的值并将组合的连接值存储在字典中以供以后使用。
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
,并从上面的cnxn
返回计算值。
def check(fld1,fld2,cnxn_sub):
rowpair = ''.join((fld1,fld2))
return cnxn_sub[rowpair]
最后,小熊猫apply
把它全部带回家。
df['connection'] = df.apply(lambda row: check(row['fld1'], row['fld2'],cnxn), axis=1)
这是我的结果,我们的“yz”连接有点偏离,idk 是你的还是我的......
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
祝你好运!
【讨论】:
我对这个问题的解释是你的“yz”行来自你的excel例子应该是=C7+(C5*C3)
感谢您的努力,我目前正在参加婚礼,无法使用笔记本电脑。我会在几天内评估你的答案。再次感谢,我会与您联系!以上是关于根据三列的值有条件地和交互地计算列的主要内容,如果未能解决你的问题,请参考以下文章
Sql Server 查询,一共三列,怎样查出第一个列值相同,第二列值最大的第三列的值?
我可以获取数据框三列的斜率并使用 python 中的值创建一个新列吗?