如何从包含数字和文本(3 或 ABC,但不包括混合物,ABC123)的 df 列中删除数字,留下空白单元格?

How do I remove numbers from a df column containing numbers and text (3 or ABC, but not mixtures, ABC123), leaving blank cells?

提问人:AndysPythonStuff 提问时间:8/28/2022 最后编辑:AndysPythonStuff 更新时间:8/28/2022 访问量:75

问:

我有一个数据帧,其中第一列,让我们称之为:df['Name'],看起来像“实际”列,而 Id 喜欢将其更改为“所需”列,以便对以下列进行操作。以下是实际和期望的输出:

姓名(实际) 姓名(必填)
字符串1 字符串1
字符串1
字符串1
字符串1
字符串2 字符串2
字符串2
字符串2
字符串2
字符串2
字符串3 字符串3
字符串3
字符串3
字符串4 字符串4
字符串4

名称之间没有固定数量的“数字”。可能是 3,可能是 300。

我有以下代码可以将名称转发到下一个名称:

df['Name'].fillna(method = 'ffill', inplace = True)

但它仅在带有数字的单元格为空时才有效。

因此,我需要先从 ['Name'] 系列中删除所有数字,留下空单元格:

名字
字符串 1
空白
空白
空白
字符串2
空白
等。。。

我找不到删除数字的方法。我尝试了我在其他类似帖子中找到的一些建议:

1)

df[df['Name'].apply(lambda x: isinstance(x, str))]

但它似乎什么也没做。

2)

df['Name'] = df['Name'].apply(lambda x: isinstance(x, str))

将整个 ['Name'] 系列(包括字符串和数字)转换为 True。

3)

df['Name'] = df[df['Name'].apply(lambda x: isinstance(x, str))]

这给出了一个值错误。

我发现结果为 2) 很奇怪,但发现 df['Name'].dtype 给了我 dtype('O'),这是 Id 以前从未见过的,但建议 ['Name'] 系列中的名称(字符串)和数字(整数/浮点数)是同一类型(numpy 对象)。不确定它是否/如何相关,但我理解这意味着 Python 将文本和数字视为同一类型。

我卡住了。关于如何删除数字并按照我解释的方式填写任何建议?

谢谢!

Python Pandas 数据帧 替换 ISinstance

评论


答:

2赞 Timeless 8/28/2022 #1

你很接近。试试这个:

import pandas as pd
import numpy as np

df = pd.DataFrame({'Name (actual)': ['string1', 334, 34, 124, 'string2', 23, 11, 89, 76, 'string3', 53, 4]})

df['Name (desired)'] = df['Name (actual)'].apply(lambda x: x if isinstance(x, str) else np.nan).ffill()

>>> print(df)

在此处输入图像描述

评论

0赞 AndysPythonStuff 8/28/2022
你好。谢谢你!您的代码工作正常,在我拥有的 df 上,它没有:它保持一切原样......文本作为文本,数字作为数字。
0赞 Timeless 8/28/2022
也许这意味着您的真实格式与您在问题中发布的格式不符。df
0赞 AndysPythonStuff 8/28/2022
是的,你是对的!我的 df 很大,是从 csv 导入的。我简化了这个问题,因为我认为这不会有任何区别。(对不起...菜鸟错误!我有一种感觉,即实例将每个条目都读作一个 str,即使它是一个数字 - 如果它没有达到“else ffill”,它一定是......我真的很困惑!
0赞 Timeless 8/28/2022
您在使用时是否指定了任何内容?dtypepd.read_csv()
0赞 AndysPythonStuff 8/28/2022
否:像这样:使用 open(file_to_use, 'r') 作为 fileObject: reader_object = pandas.read_csv(fileObject, delimiter=';', decimal=',', header=0, names=('Noticia','Ativo','Variacao','Maximo','Ultimo','Minimo','Negocios','Semana',)) “Noticia”列是文本条目后跟数字的列,有时是空的。它的这一列我试图清理,删除所有数字,然后用文本填充所有空白。
2赞 mozway 8/28/2022 #2

使用效率不高,最好使用向量方法:apply

# identify numbers:
m = pd.to_numeric(df['Name'], errors='coerce').notna()

# mask and ffill:
df['Name'] = df['Name'].mask(m).ffill()

示例(为清楚起见,分配给新列“名称 2”);

       Name    Name2
0   string1  string1
1       123  string1
2       123  string1
3       123  string1
4   string2  string2
5       123  string2
6       123  string2
7       123  string2
8       123  string2
9   string3  string3
10      123  string3
11      123  string3

评论

1赞 AndysPythonStuff 4/1/2023
嗨,莫兹威。对不起,我没有投赞成票,我当时不知道这是一回事。我最后使用了你的想法,效果很好。感谢您的想法和教训!