如何比较列和递归返回值?

时间:2020-04-07 19:17:43

标签: python pandas dataframe

我有一个看起来像这样的数据框:

data_dict = {'factor_1' : np.random.randint(1, 5, 10), 'factor_2' : np.random.randint(1, 5, 10), 'multi' : np.random.rand(10), 'output' : np.NaN}
df = pd.DataFrame(data_dict)

我在实施此比较时陷入困境:

  1. 如果factor_1factor_2值匹配,则output = 2 * multi(此处2是基本值)。继续扫描下一行。

  2. 如果factor_1factor_2的值不匹配,则:

    • output = -2。扫描下一行。
    • 如果在第R行之前因子值仍然不匹配,则将output的值分别指定为$ -2 ^ 2,-2 ^ 3,...,-2 ^ R $。
    • 当因子值在行R+1上匹配时,然后为output赋值$ 2 ^(R + 1)* multi $。
    • 重复该过程

最终结果将如下所示:

enter image description here

3 个答案:

答案 0 :(得分:1)

flag = False
cols = ('factor_1', 'factor_2', 'multi')
z = zip(*[data_dict[col] for col in cols])
for i, (f1, f2, multi) in enumerate(z):
    if f1==f2: 
        output = 2 * multi
        flag = False
    else:
        if flag:
            output *= 2
        else:
            output = -2
            flag = True
    data_dict['output'][i] = output

棘手的部分是flag变量,它告诉您上一行是否匹配。

答案 1 :(得分:1)

我提出的解决方案可能更难阅读,但我认为它可以按您的意愿工作。它结合了

  • numpy.where()以便根据条件创建列,
  • pandas.DataFrame.shift()pandas.DataFrame.cumsum()用连续的相似值标记不同的组,并且
  • pandas.DataFrame.rank(),以构造用于先前制作的library(dplyr) as_tibble(forCount) %>% filter(n ==1) %>% group_by(AssemblyFile) %>% summarise(CPGene = toString(CPGene)) %>% count(CPGene) # A tibble: 2 x 2 # CPGene n #* <chr> <int> #1 CTX-M-27, KPC-2 1 #2 KPC-2 5 列的幂矢量。

代码如下。

df['output']

答案 2 :(得分:1)

此解决方案不使用递归:

# sample data
np.random.seed(1)
data_dict = {'factor_1' : np.random.randint(1, 5, 10), 'factor_2' : np.random.randint(1, 5, 10), 'multi' : np.random.rand(10), 'output' : np.NaN}
df = pd.DataFrame(data_dict)

# create a mask
mask = (df['factor_1'] != df['factor_2'])
# get the cumsum from the mask
df['R'] = mask.cumsum() - mask.cumsum().where(~mask).ffill().fillna(0)

# use np.where to create the output
df['output'] = np.where(df['R'] == 0, df['multi']*2, -2**df['R'])

   factor_1  factor_2     multi     output    R
0         2         1  0.419195  -2.000000  1.0
1         4         2  0.685220  -4.000000  2.0
2         1         1  0.204452   0.408904  0.0
3         1         4  0.878117  -2.000000  1.0
4         4         2  0.027388  -4.000000  2.0
5         2         1  0.670468  -8.000000  3.0
6         4         3  0.417305 -16.000000  4.0
7         2         2  0.558690   1.117380  0.0
8         4         3  0.140387  -2.000000  1.0
9         1         1  0.198101   0.396203  0.0