在 Pandas DataFrame 中的每个项目前面加上一个升序数字(如果它有值)

Prefixing each item in a Pandas DataFrame with an ascending number if it has a value

提问人:Dredd 提问时间:11/17/2023 最后编辑:Dredd 更新时间:11/17/2023 访问量:51

问:

我目前正在尝试找到此问题的最佳解决方案:

我将 csv 导入 Python,有些单元格有值,有些则没有。我想遍历数据帧,如果单元格有值,则向其附加一个数字,每次新单元格具有文本时都会递增。然后,这些附加值将保存到新列中

我还将每段文本保存到另一个列表中,因为我需要在下一步中使用它们()。下面的代码产生了正确的输出,我只是想知道有没有更有效的方法来做到这一点?out

我考虑过或类似的东西,但无法从中增加计数。np.where()

import pandas as pd

df = pd.DataFrame(
    [["", "c", "e"], ["a", "", ""], ["b", "d", "f"]], 
    columns = ["x", "y", "z"]
)
count = 1
out = []

# Loop over each column
for col in df.columns:
      tmp = []
      # Loop over each entry, if cell has text, add prefix
      for text in df[col]:
        if text:
          tmp.append(str(count) + "-" + text)
          out.append(text)
          count += 1
        else:
          tmp.append("")
      # Add prefixed column to df    
      df["pre-" + col] = tmp

给出输出:输出 DF

这不一定必须按列进行,只要数字与 中的顺序相对应即可。out

编辑:

Mozway 的答案是使用 lambda 函数,因为我想要一些数字格式。

df = pd.DataFrame(
    [["", "c", "e"], ["a", "", ""], ["b", "d", "f"]], 
    columns = ["x", "y", "z"]
)
s = df.replace('', np.nan).T.stack()
out = (s.notna().cumsum().apply(
    lambda x: "{0:04}-".format(x))+s).unstack().T.fillna('')
df = df.join(out.add_prefix("pre-"))
python pandas 数据帧 numpy

评论


答:

1赞 mozway 11/17/2023 #1

如果您不关心计数器的顺序,请使用 stack 进行整形,使用 cumsum 进行递增,然后取消堆栈

s = df.replace('', np.nan).stack()

out = (s.notna().cumsum().astype(str)+'-'+s
      ).unstack().fillna('')

输出:

     x    y    z
0       1-c  2-e
1  3-a          
2  4-b  5-d  6-f

如果顺序很重要:

s = df.replace('', np.nan).T.stack()

out = (s.notna().cumsum().astype(str)+'-'+s
      ).unstack().T.fillna('')

或者使用

m = df.ne('').to_numpy()

tmp = (pd.DataFrame(m.T.cumsum(axis=None).reshape(m.shape).T,
                    index=df.index, columns=df.columns)
         .astype(str).add('-')
         .where(m, '')
      )

out = tmp+df

输出:

     x    y    z
0       3-c  5-e
1  1-a          
2  2-b  4-d  6-f

若要将输出合并到原始 DataFrame,请联接

df.join(out.add_prefix('pre-'))

输出:

   x  y  z pre-x pre-y pre-z
0     c  e         3-c   5-e
1  a         1-a            
2  b  d  f   2-b   4-d   6-f