【问题标题】:Conditional statement between columns and rows in dataframe数据框中列和行之间的条件语句
【发布时间】:2019-07-08 05:43:24
【问题描述】:

我想创建到列,它基于 if 语句在同一行中的值之间创建一个值,如果需要,在上面的行中创建一个值。 我有一个常数 A 和 df

A = 0.5
          FID_1          b          c        d            e
75907       nan 33021647.00   27014.12 27014.12        1.00
75858 159510.00 32888862.00   16532.64 28797.05        0.57
75859 159510.00 32888862.00   12264.41 28797.05        0.43
75795       nan 32869718.00   24218.16 24218.16        1.00
75518       nan 32574894.00   13304.45 13304.45        1.00

我想创建另一个名为f 的列,它会告诉我e 中的值是否大于A,或者对于b 中的给定值。如果正确,则该值为 1。

上述df的示例:

          FID_1          b          c        d            e    f
75907       nan 33021647.00   27014.12 27014.12        1.00    1
75858 159510.00 32888862.00   16532.64 28797.05        0.57    1
75859 159510.00 32888862.00   12264.41 28797.05        0.43    0
75795       nan 32869718.00   24218.16 24218.16        1.00    1
75518       nan 32574894.00   13304.45 13304.45        1.00    1

更棘手的是,如果我将A 的值更改为0.6。在这种情况下,我想查看b 中的每个数字,如果b 中值的第一行在e 中的值大于A,如果不是,我想查看e 中相同值sum 的第二行,并检查它是否大于A。dfA=0.6 看起来像这样:

          FID_1          b          c        d            e    f
75907       nan 33021647.00   27014.12 27014.12        1.00    1
75858 159510.00 32888862.00   16532.64 28797.05        0.57    0
75859 159510.00 32888862.00   12264.41 28797.05        0.43    1
75795       nan 32869718.00   24218.16 24218.16        1.00    1
75518       nan 32574894.00   13304.45 13304.45        1.00    1

在这种情况下,代码将 df 的第三行中的 0.57 和 0.43 相加。

如果情况并非如此,代码将查找b 中相同值的第三、第四、...行 - 如果它甚至存在的话。

这是创建e 列的代码

df['e'] = df.apply(lambda row: row.c / row.d, axis=1)

我为f 列尝试了类似的方法,但我不知道如何在同一代码中输入if statement

这是我的解决方案的开始:

def STAcondition (row):
   if row['e'] > A :
      return 0
   if row['e'] < A :
      return 1
   return 'Other'

df['f'] =  df.apply (lambda row: STAcondition (row),axis=1)

【问题讨论】:

  • 第一部分的答案就是df['f'] = (df['e'] &gt; a).astype(int)。第二个更棘手,你需要一个循环。而且你的逻辑不太合理 - 为什么第二行不应该是 1,因为它和前一行的总和大于 A
  • 是的。对于b 中的值32888862,f 中的第一行是0,第二行是1,因为e 中的sum 大于A,是的。棘手。我正在尝试结合.shiftnp.where命令找到解决方案

标签: python pandas dataframe if-statement conditional


【解决方案1】:

也许尝试分多个步骤创建 f。 如果我理解正确,你的伪算法应该是这样的:

  • 要在 b 中查找的输入值
  • 'e' 中的值是否大于 A?
    • 如果为真,则 f 中的值 = 1
    • 如果为 false,则确定要查找的值是否在 b 中具有重复项。获取他们的索引。
      • 在您要查找的值的最后一次出现的行中,在 f 列中,对重复项的值求和。
      • 总和是否大于 A?
        • 如果为真,则 f 中的值 = 1
        • 如果为 false,则 f 中的值 = 0

这是我拟定的:

import pandas as pd
import numpy.random as npr
import numpy as np

# Dummy data
dfInit = {
    'FID_1':npr.randint(0,10,10),
    'b':npr.randint(0,10,10),
    'c':npr.randint(0,10,10),
    'd':npr.randint(0,10,10),
    'e':npr.randint(0,10,10)
}
dfIndex = np.arange(0,10)
df = pd.DataFrame(data=dfInit, index=dfIndex)

# Algo
df['f'] = np.zeros(10)
A = 6

def letsMakeAnF(value):
    # check if value is in b
    if value in df['b'].unique():
        occurrenceMatch = df.loc[df['b'] == value,:] 
    else:
        print('value not in b series')
        return

    if occurrenceMatch['e'].iloc[0] > A:
        df['f'].ix[occurrenceMatch.index[0]] == 1
    else:
        if np.sum(occurrenceMatch['b']) > A:
            df['f'].ix[occurrenceMatch.index[-1]] = 1

#Generate random 'wanted' values
values = [npr.randint(0, 10) for x in range(10)]

#Iterate over the values and modify the DF. Note that in this case
#df is a global variable
for value in values:
   letsMakeAnF(value)

希望对你有帮助!

【讨论】:

  • 我收到loc 的错误 - IndexError:单个位置索引器超出范围。我喜欢它的逻辑,只需要先修复错误
  • 但在这种情况下,您将 'b' 中的值固定为 'value',这在整个 df 中是不同的。
  • 我想我知道您为什么会收到错误消息。 “值”是否存在于“b”中?如果不是,occurrenceMatch 是一个空的 DF,这会破坏算法也许应该在执行其余的情况之前捕获这种情况。
  • 如果您需要迭代不同的“值”,您可以随时将代码重构为以“值”为参数的函数,然后循环遍历您需要的值!我只是想让答案尽可能简单,这样我们就可以进入重点:)
  • 您能否举个例子,如何将代码重构为一个以“值”为参数的函数,并在此示例中循​​环遍历列中的值?
猜你喜欢
  • 2021-06-19
  • 1970-01-01
  • 1970-01-01
  • 2016-07-14
  • 2019-02-17
  • 2019-10-15
  • 2011-08-15
  • 2022-01-23
相关资源
最近更新 更多