【问题标题】:Creating a column in Dataframe if values exist in other columns如果值存在于其他列中,则在 Dataframe 中创建列
【发布时间】:2018-06-09 11:40:37
【问题描述】:

我有一个包含许多列的 DataFrame。有 3 列包含空白行,或者,如果该行对应于列变量,则具有随机数字/字母字符串。我想获取这些数据并创建另一列,其中包含一个字符串,其中包含每行的变量名称。

例如:

    raw_data['A']
Out[192]: 
0        00Q2400000GUxMjEAL
1        00Q2400000G5QDzEAN
2                       NaN
3                       NaN
4                       NaN
5                       NaN

到目前为止,我已经尝试编写一个函数来应用,但它只为每一行返回“xyz”。

def type(row):
    if row['A'] is not None:
        return 'xyz'
    elif row['B'] is not None:
        return 'acb'
    else:
        return 'efg'

raw_data['TUV'] = raw_data.apply(lambda row: type(row), axis = 1)

任何帮助将不胜感激。

【问题讨论】:

  • 如果两个列值都具有NaN 或都具有字符串/数字值,会发生什么情况?

标签: python python-3.x pandas loops dataframe


【解决方案1】:

使用pd.notnull

def type(row):

    if pd.notnull(row['A']):
        return 'xyz'
    elif pd.notnull(row['B']):
        return 'acb'
    else:
        return 'efg'

df['TUV'] = df.apply(lambda row: type(row), axis = 1)

更好地编辑以使用 pd.notnull

【讨论】:

  • 非常感谢曼努埃尔的帮助!出于某种原因,df['TUV'] 中的每一行都显示为“xyz”。我的 lambda 函数可能有问题吗?似乎它将第一行中的比较结果应用于整个系列。
  • 您的lamba函数完美运行,您的函数类型(行)不是,您必须将“row['A'] is not None”更改为“pd.notnull(row['A'])” ,正如我的回答所表明的那样。
  • 对不起,我已更改为 pd.notnull() 但未在函数中包含“行”,这就是它没有迭代的原因。再次感谢!
【解决方案2】:

对于更大的数据集,apply 可能会很慢。
即使只有 10,000 行,您也可以通过简单的索引操作在此任务上获得大约 25 倍的加速

以下是一些示例数据:

N = 10000
data = {"A": np.random.choice([1, None], size=N),
        "B": np.random.choice([1, None], size=N)}
df = pd.DataFrame(data)

df.head()
      A     B
0     1     1
1  None     1
2     1     1
3     1     1
4  None  None

使用基本赋值和索引:

%%timeit

df["TUV"] = "efg"
df.loc[df.A.notnull(), "TUV"] = "xyz"
df.loc[df.B.notnull(), "TUV"] = "acb"
# 6.15 ms ± 211 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

使用apply

%%timeit

def type(row):

    if pd.notnull(row['A']):
        return 'xyz'
    elif pd.notnull(row['B']):
        return 'acb'
    else:
        return 'efg'

df['TUV2'] = df.apply(lambda row: type(row), axis = 1)
# 152 ms ± 1.5 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

df.TUV.equals(df.TUV2) # True

【讨论】:

  • 非常快的解决方案,但是我相信返回值和函数中的不一样,是df.loc[df.B.notnull(), "TUV"] = 的顺序"acb" 和 df.loc[df.A.notnull(), "TUV"] = "xyz" 正确吗?
猜你喜欢
  • 1970-01-01
  • 2016-02-10
  • 2017-07-29
  • 1970-01-01
  • 2021-12-30
  • 1970-01-01
  • 2022-09-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多