如何删除分隔符最后一次出现后的内容?Pandas TypeError问题处理
解决:移除DataFrame列中最后一个下划线后的内容
需求
删除HTAN Parent Biospecimen ID列里每个值最后一个_分隔符之后的所有内容。
报错代码
import pandas as pd df_2["HTAN Parent Biospecimen ID"] = df_2["HTAN Parent Biospecimen ID"].str.rsplit("_", 1).str.get(0)
报错信息
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Input In [41], in <cell line: 3>() 1 # BulkRNA-seqLevel1 2 df_2 = pd.read_csv("syn39282161.csv", sep=",") ----> 3 df_2["HTAN Parent Biospecimen ID"] = df_2["HTAN Parent Biospecimen ID"].str.rsplit("_", 1).str.get(0) 4 df_2.head() File ~/.local/lib/python3.9/site-packages/pandas/core/strings/accessor.py:129, in forbid_nonstring_types.<locals>._forbid_nonstring_types.<locals>.wrapper(self, *args, **kwargs) 124 msg = ( 125 f"Cannot use .str.{func_name} with values of " 126 f"inferred dtype '{self._inferred_dtype}'." 127 ) 128 raise TypeError(msg) --> 129 return func(self, *args, **kwargs) TypeError: rsplit() takes from 1 to 2 positional arguments but 3 were given
测试数据
pd.DataFrame({'Component': {0: 'BulkRNA-seqLevel1', 1: 'BulkRNA-seqLevel1', 2: 'BulkRNA-seqLevel1', 3: 'BulkRNA-seqLevel1'}, 'Filename': {0: 'B001A001_1.fq.gz', 1: 'B001A001_2.fq.gz', 2: 'B001A006_1.fq.gz', 3: 'B001A006_2.fq.gz'}, 'File Format': {0: 'fastq', 1: 'fastq', 2: 'fastq', 3: 'fastq'}, 'HTAN Parent Biospecimen ID': {0: 'HTA10_07_001', 1: 'HTA10_07_001', 2: 'HTA10_07_006', 3: 'HTA10_07_006'}})
期望输出
pd.DataFrame({'Component': {0: 'BulkRNA-seqLevel1', 1: 'BulkRNA-seqLevel1', 2: 'BulkRNA-seqLevel1', 3: 'BulkRNA-seqLevel1'}, 'Filename': {0: 'B001A001_1.fq.gz', 1: 'B001A001_2.fq.gz', 2: 'B001A006_1.fq.gz', 3: 'B001A006_2.fq.gz'}, 'File Format': {0: 'fastq', 1: 'fastq', 2: 'fastq', 3: 'fastq'}, 'HTAN Parent Biospecimen ID': {0: 'HTA10_07_001', 1: 'HTA10_07', 2: 'HTA10_07', 3: 'HTA10_07'}})
问题原因与解决办法
原因
报错的核心是pandas的str.rsplit方法里,分割次数不能直接用位置参数传递,必须用关键字参数n来指定。另外如果列里存在非字符串类型的值(比如空值、数字),也会触发类似错误,所以最好先把列转成字符串类型。
修正后的代码
方案一:规范使用rsplit参数
import pandas as pd # 先把列转为字符串类型,避免非字符串值引发错误 df_2["HTAN Parent Biospecimen ID"] = df_2["HTAN Parent Biospecimen ID"].astype(str) # 用n=1指定只从右侧分割1次 df_2["HTAN Parent Biospecimen ID"] = df_2["HTAN Parent Biospecimen ID"].str.rsplit("_", n=1).str.get(0)
方案二:用rpartition更简洁
rpartition会直接把字符串从最后一个分隔符处分成三部分(前缀、分隔符、后缀),取第一部分即可:
import pandas as pd df_2["HTAN Parent Biospecimen ID"] = df_2["HTAN Parent Biospecimen ID"].astype(str).str.rpartition("_")[0]
验证效果
把测试数据代入修正后的代码,就能得到符合预期的输出——HTAN Parent Biospecimen ID列里的每个值都去掉了最后一个下划线及之后的内容。
内容的提问来源于stack exchange,提问作者Anon
相关产品推荐
相关产品推荐

