删除 pandas DataFrame 列中字符串条目的结尾
Posted
技术标签:
【中文标题】删除 pandas DataFrame 列中字符串条目的结尾【英文标题】:Remove ends of string entries in pandas DataFrame column 【发布时间】:2016-08-28 08:38:42 【问题描述】:我有一个 pandas 数据框,其中有一列是文件列表
import pandas as pd
df = pd.read_csv('fname.csv')
df.head()
filename A B C
fn1.txt 2 4 5
fn2.txt 1 2 1
fn3.txt ....
....
我想从filename
中的每个条目中删除文件扩展名.txt
。我该如何做到这一点?
我试过了:
df['filename'] = df['filename'].map(lambda x: str(x)[:-4])
但是当我之后用df.head()
查看列条目时,什么都没有改变。
如何做到这一点?
【问题讨论】:
您的数据是'fn1.txt'
还是fn1.txt
?那么你有引用字符串作为你的数据吗?
@EdChum 我看不到引号
【参考方案1】:
您可以使用str.rstrip
删除结尾:
df['filename'] = df['filename'].str.rstrip('.txt')
应该工作
【讨论】:
不知道它应该有效,但问题仍然是您的数据是否有引号? 当我使用df.head()
时,我看不到引号
所以,当我尝试上面的代码时,我得到以下错误 'AttributeError: 'str' object has no attribute 'str''
我认为rstrip
方法可能有问题,如果文件的最后一个字符包含t
、e
或x
。然后这个字符被删除。试试df = pd.DataFrame('A': 0: 2, 1: 1, 'C': 0: 5, 1: 1, 'B': 0: 4, 1: 2, 'filename': 0: "test.txt", 1: "x.txt", columns=['filename','A','B', 'C'])
抱歉,不是e
。只有字符 t
和 x
。【参考方案2】:
我认为您可以将str.replace
与正则表达式.txt$'
一起使用($
- matches the end of the string):
import pandas as pd
df = pd.DataFrame('A': 0: 2, 1: 1,
'C': 0: 5, 1: 1,
'B': 0: 4, 1: 2,
'filename': 0: "txt.txt", 1: "x.txt",
columns=['filename','A','B', 'C'])
print df
filename A B C
0 txt.txt 2 4 5
1 x.txt 1 2 1
df['filename'] = df['filename'].str.replace(r'.txt$', '')
print df
filename A B C
0 txt 2 4 5
1 x 1 2 1
df['filename'] = df['filename'].map(lambda x: str(x)[:-4])
print df
filename A B C
0 txt 2 4 5
1 x 1 2 1
df['filename'] = df['filename'].str[:-4]
print df
filename A B C
0 txt 2 4 5
1 x 1 2 1
编辑:
rstrip
可以删除更多的字符,如果字符串的末尾包含一些条带字符串的字符(在这种情况下.
,t
,x
):
例子:
print df
filename A B C
0 txt.txt 2 4 5
1 x.txt 1 2 1
df['filename'] = df['filename'].str.rstrip('.txt')
print df
filename A B C
0 2 4 5
1 1 2 1
【讨论】:
我得到以下AttributeError
: AttributeError: 'str' object has no attribute 'str'
尝试将列 filename
转换为 string
- df['filename'] = df['filename'].astype(str)
即使将列转换为字符串,这些方法都不起作用
它适用于我的解决方案中的数据框? df = pd.DataFrame('A': 0: 2, 1: 1, 'C': 0: 5, 1: 1, 'B': 0: 4, 1: 2, 'filename': 0: "txt.txt", 1: "x.txt", columns=['filename','A','B', 'C'])
?
您的pandas
是什么版本? print pd.show_versions()
【参考方案3】:
你可能想要:
df['filename'] = df.apply(lambda x: x['filename'][:-4], axis = 1)
【讨论】:
如果不是固定大小的 -4 你我需要更灵活的说法,去掉逗号或句点之后的最后一个词,怎么样?【参考方案4】:使用列表理解
df['filename'] = [x[:-4] for x in df['filename']]
【讨论】:
如果最后一个或第一个字符是“X”,我想删除最后一个或第一个字符。请举例【参考方案5】:2021 年更新 + 速度测试
从pandas 1.4开始,相当于str.removesuffix,实现了pandas.Series.str.removesuffix,所以可以使用
df['filename'].str.removesuffix('.txt')
速度测试
tl;dr: 最快的是
dat["fname"].map(lambda x: x[:-4] if x[-4:] == ".txt" else x)
在速度测试中,我想考虑这个 SO 页面中收集的不同方法。我排除了rstrip
,因为它也会去除.txt
以外的结尾,并且由于正则表达式包含条件,因此修改其他函数也是公平的,以便它们仅在它们是.txt
时删除最后4个字符.
测试代码是
import pandas as pd
import time
ITER = 10
def rm_re(dat: pd.DataFrame) -> pd.Series:
"""Use regular expression."""
return dat["fname"].str.replace(r'.txt$', '', regex=True)
def rm_map(dat: pd.DataFrame) -> pd.Series:
"""Use pandas map, find occurrences and remove with []"""
where = dat["fname"].str.endswith(".txt")
dat.loc[where, "fname"] = dat["fname"].map(lambda x: x[:-4])
return dat["fname"]
def rm_map2(dat: pd.DataFrame) -> pd.Series:
"""Use pandas map with lambda conditional."""
return dat["fname"].map(lambda x: x[:-4] if x[-4:] == ".txt" else x)
def rm_apply_str_suffix(dat: pd.DataFrame) -> pd.Series:
"""Use str method suffix with pandas apply"""
return dat["fname"].apply(str.removesuffix, args=(".txt",))
def rm_suffix(dat: pd.DataFrame) -> pd.Series:
"""Use pandas removesuffix from version 1.6"""
return dat["fname"].str.removesuffix(".txt")
functions = [rm_map2, rm_apply_str_suffix, rm_map, rm_suffix, rm_re]
for base in range(12, 23):
size = 2**base
data = pd.DataFrame("fname": ["fn"+str(i) for i in range(size)])
data.update(data.sample(frac=.5)["fname"]+".txt")
for func in functions:
diff = 0
for _ in range(ITER):
data_copy = data.copy()
start = time.process_time()
func(data_copy)
diff += time.process_time() - start
print(diff, end="\t")
输出如下图:
从图中可以看出,最慢的解是正则表达式,最快的是带条件的pandas.Series.map
。在更高版本的 pandas 中,这可能会改变,我预计 pandas.Series.str.removesuffix
会有所改进,因为它在矢量化方面具有更大的潜力。
必须从 2021 年 11 月 30 日起从源代码安装 Pandas,因为 1.4 版仅处于开发阶段。我按照pandas dev repo 的说明安装它,克隆项目并使用python setup.py install
安装。
我的机器:
AMD 锐龙 5 2400G 带 Radeon Vega 显卡,3.60 GHz Windows 10 20H2 Python 3.10.0,pandas.版本 '1.4.0.dev0+1267.gaee662a7e3',numpy.版本 '1.21.4'【讨论】:
以上是关于删除 pandas DataFrame 列中字符串条目的结尾的主要内容,如果未能解决你的问题,请参考以下文章
从 Pandas DataFrame 列中删除特定符号(unicode)[重复]
删除pandas dataframe index中的字符范围
pandas使用duplicated函数删除dataframe中重复列名称的数据列默认保留重复数据列中的第一个数据列(removing duplicate columns in dataframe)
如何从列类型列表中删除 pandas DataFrame 中的空值