根据三列的值有条件地和交互地计算列

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 = xfld2 = x,然后

第 2 步: 检查 fld1 = x 的情况是否有更多唯一值 fld2

步骤 3: 如果有另一个唯一值 fld2fld1 = x 相关联(在这两个唯一值存在,xy),将 Step 1 中的 relationship 值添加到 fld1 = xrelationship 列和 fld2 的下一个唯一值(在此示例中为 fld2 = y是下一个唯一值)乘以关系的倒数(在本例中为 fld1 = yfld2 = x

第 4 步:重复第 2 步,直到 fld2fld1 = 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 的第一个字母相同。第二个字母总是notfld1。因此,这里有一种详尽且可能不是 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,它会提取你的fld1fld2,并从上面的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 携手R 计算两组数据相关性

我可以获取数据框三列的斜率并使用 python 中的值创建一个新列吗?

在一个表中添加两列的值并插入第三列

怎样在一条sql语句中将第一列和第二列加和的值作为第三列的值

熊猫数据框条件 .mean() 取决于特定列中的值