【问题标题】:Pandas - iterate over rows in specific column and find empty cellsPandas - 遍历特定列中的行并找到空单元格
【发布时间】:2021-08-17 04:30:07
【问题描述】:

我有一个超过 50 000 行的数据框。

输入:

我试图遍历行直到第一个空单元格,然后仅当 par 存在时才复制 id 的值。不幸的是,这不起作用。

换句话说,我的目标是将 par 替换为 column1 的值(id_1, id_2, id_3)到 column3强>分别。 输出将类似于:

任何想法或帮助将不胜感激。提前谢谢大家!

【问题讨论】:

  • np.where(df['Column3'] == 'par', df['Column1'], np.nan)?
  • @It_is_Chris 没用,np.where 不能以这种方式使用。查看 Column1 中的值。

标签: python pandas dataframe


【解决方案1】:

您可以使用.where()ffill()Column1 的每一行中使用id 值填充每组相同的id。然后使用.mask()Column3par的值更改为同一行中的这些id值,如下所示:

Col1_id = df['Column1'].where(df['Column1'].str.startswith('id_')).ffill()

df['Column3'] = df['Column3'].mask(df['Column3'] == 'par', Col1_id)

结果:

print(df)

   Column1 Column2 Column3
0     id_1     NaN     NaN
1    n="1"   whose    id_1
2    n="2"  theirs    id_1
3    n="3"      am    id_1
4      NaN     NaN     NaN
5     id_2     NaN     NaN
6    n="4"      in    id_2
7    n="5"     out    id_2
8      NaN     NaN     NaN
9     id_3     NaN     NaN
10   n="6"      in    id_3
11   n="7"     out    id_3

【讨论】:

  • @Artemis Column3 中是否可能会有除 parNaN 之外的值?如果是,请注意 Arkadiusz 的解决方案可能会使这些值 NaN 而我的解决方案应该适用于此。
  • 我在我的答案中添加了一条评论,并解释了在这种情况下可以做什么。从有问题的帖子中,我们可以得出第 3 列中有“par”和“nan”的结论。如果还有更多 - 这是用户的决定。他可以决定是将“nan”放在那里还是保留现有值更好。
  • @SeaBean 非常感谢您的澄清。幸运的是,它只包含 par 和 NaN,但感谢您的解释,我不会这样做。
【解决方案2】:
  1. 使用 numpy.split 将 DataFrame 拆分为空行。
  2. 如果“par”在 Column3 中,则使用 str.replace 将 Column3 中的所有“par”替换为“Column 1”中的第一个非空值
  3. 将修改后的“块”附加到输出中。

解决办法:

import numpy as np

output = pd.DataFrame()
for chunk in np.split(df, df[df.isnull().all(1)].index):
    if "par" in chunk["Column3"].tolist():
        chunk["Column3"] = chunk["Column3"].str.replace("par", chunk["Column1"].dropna().iat[0])
    output = output.append(chunk)

>>> output
   Column1 Column2 Column3
0     id_1    None    None
1    n="1"   whose    id_1
2    n="2"  theirs    id_1
3    n="3"      am    id_1
4     None    None    None
5     id_2    None    None
6    n="4"      in    id_2
7    n="5"     out    id_2
8     None    None    None
9     id_3    None    None
10   n="6"      in    id_3
11   n="7"     out    id_3

【讨论】:

  • 感谢您的详细解答。为简单起见,我没有使用我的 df 的确切格式(大错特错,我深表歉意)。 df 以 3 个补充行开头,不以 par 结尾。第一行:所有列都是空的第二行:column1:,column2 和column3:空第三:所有列都是空的并且以column1 结尾:,column2 和column3:空
  • 格式化在 cmets 中完全丢失了,所以我不明白你的意思。您介意更新您的问题以解释问题所在吗?
  • 我检查了您的代码,好像数据框直接从行 id_1 开始,第 3 列以 par 结束,并且它有效。我没有从一开始就提供正确的格式是我的错。再次感谢您!
【解决方案3】:

你可以这样做:

import numpy as np

df['Column3'] = np.where(df['Column3'].eq('par'),
                         df['Column1'].where(df['Column1'].str.contains('id')).ffill(),
                         np.nan)

输出:

    Column1  Column2  Column3
0      id_1      NaN      NaN
1     n="1"    whose     id_1
2     n="2"   theirs     id_1
3     n="3"       am     id_1
4      id_2      NaN      NaN
5     n="4"       in     id_2
6     n="5"      out     id_2
7      id_3      NaN      NaN
8     n="6"       in     id_3
9     n="7"      out     id_3

编辑:

如果 Column3 中还有 'par' 以外的其他值,可以将 df['Column3'] 代替 np.nan 放在函数末尾。您是否想在该列中为“par”以外的值添加“nan”或保留已存在的值,这是您的决定。

【讨论】:

    猜你喜欢
    • 2019-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多