查找包含特定字符串的列名

273

我有一个带列名的数据框,想要查找包含某个字符串但不完全匹配的列名。我正在搜索包含'spike'的列名,例如'spike-2''hey spike''spiked-in''spike'部分总是连续的)。

我想将列名作为字符串或变量返回,以便稍后使用df['name']df[name]访问该列。我已尝试各种方法,但都没有成功。有什么提示吗?

8个回答

410

只需迭代DataFrame.columns,以下是一个例子,你最终将得到一个匹配的列名列表:

import pandas as pd

data = {'spike-2': [1,2,3], 'hey spke': [4,5,6], 'spiked-in': [7,8,9], 'no': [10,11,12]}
df = pd.DataFrame(data)

spike_cols = [col for col in df.columns if 'spike' in col]
print(list(df.columns))
print(spike_cols)

输出:

['hey spke', 'no', 'spike-2', 'spiked-in']
['spike-2', 'spiked-in']

解释:

  1. df.columns 返回一个列名的列表。
  2. [col for col in df.columns if 'spike' in col] 遍历列表 df.columns 中的每个元素,用变量 col 代表元素,并将包含 'spike' 的元素添加到结果列表中。这种语法叫做列表推导式

如果你只想得到与这些列名匹配的结果数据集,可以这样做:

df2 = df.filter(regex='spike')
print(df2)

输出:

   spike-2  spiked-in
0        1          7
1        2          8
2        3          9

27
供您参考,DataFrame.filter 的功能是筛选数据帧中的行或列(您可以提供正则表达式来筛选)。 - Jeff
2
@xndrme,您如何编写正则表达式来排除与某个正则表达式匹配的特定列,而不是包含它们? - Dhruv Ghulati
3
您可以在df[df.columns.drop(spike_cols)]中删除不需要的列,其中splike_cols是您使用不想要的正则表达式获得的列列表。这样,您将获得一个不包含该列表中所列出的列的DataFrame。 - Alvaro Fuentes
3
更简洁的代码:df[[col for col in df.columns if "spike" in col]] - WindChimes
4
@JacoSolari 提供了两种选取DataFrame列的方式,分别是通过列表推导式筛选包含'spike'、'foo'或'bar'关键词的列,以及使用正则表达式在列名中匹配'spike'、'foo'或'bar'的列。 - Alvaro Fuentes
显示剩余3条评论

142

这个答案使用DataFrame.filter方法,无需使用列表推导式即可实现此操作:

import pandas as pd

data = {'spike-2': [1,2,3], 'hey spke': [4,5,6]}
df = pd.DataFrame(data)

print(df.filter(like='spike').columns)

仅会输出 'spike-2'。你也可以像之前的一些评论中建议的那样使用正则表达式:

print(df.filter(regex='spike|spke').columns)

将输出两列:['spike-2','hey spke']


我有很多列,我使用了这段代码,但它似乎跳过了一些名称!在这个例子中,想象一下运行这段代码,却没有返回“hey spke”列!! - PM0087
如何按名称排除某些列?我们该怎么做? - MrSoLoDoLo
你可以使用负向先行断言(regex='^(?!spke)')或获取一个布尔向量来处理列,例如df.columns.str.contains('spke')。 - Ben

47

您还可以使用df.columns[df.columns.str.contains(pat = 'spike')]

data = {'spike-2': [1,2,3], 'hey spke': [4,5,6], 'spiked-in': [7,8,9], 'no': [10,11,12]}
df = pd.DataFrame(data)

colNames = df.columns[df.columns.str.contains(pat = 'spike')] 

print(colNames)

这将输出列名:'spike-2','spiked-in'

了解更多关于pandas.Series.str.contains的内容。


40
# select columns containing 'spike'
df.filter(like='spike', axis=1)

您也可以通过名称、正则表达式进行选择。请参考:pandas.DataFrame.filter


2
到目前为止,最简单的解决方案。简单但功能强大! - ciurlaro
1
这是一个错误的答案。请注意,问题要求返回具有给定字符串或模式(例如 spike)的“列名”。 - DataFramed

17
df.loc[:,df.columns.str.contains("spike")]

1
虽然它并没有完全回答原始问题,但我真的很喜欢这个解决方案,因为它直接返回了切片的DataFrame(这实际上也可能是OP想要的)。 - malvoisen

10
另一种方法是返回包含所需列的数据框子集:
df[df.columns[df.columns.str.contains("spike|spke")]]


在正则表达式中,'&' 运算符和 '|' 运算符的工作方式相同吗? - undefined

4
您也可以使用以下代码:
spike_cols =[x for x in df.columns[df.columns.str.contains('spike')]]

1

获取名称并根据开始、包含和结束进行子集化:

# from: https://dev59.com/qGEi5IYBdhLWcg3wbr3S
# from: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.str.contains.html
# from: https://cmdlinetips.com/2019/04/how-to-select-columns-using-prefix-suffix-of-column-names-in-pandas/
# from: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.filter.html




import pandas as pd



data = {'spike_starts': [1,2,3], 'ends_spike_starts': [4,5,6], 'ends_spike': [7,8,9], 'not': [10,11,12]}
df = pd.DataFrame(data)



print("\n")
print("----------------------------------------")
colNames_contains = df.columns[df.columns.str.contains(pat = 'spike')].tolist() 
print("Contains")
print(colNames_contains)



print("\n")
print("----------------------------------------")
colNames_starts = df.columns[df.columns.str.contains(pat = '^spike')].tolist() 
print("Starts")
print(colNames_starts)



print("\n")
print("----------------------------------------")
colNames_ends = df.columns[df.columns.str.contains(pat = 'spike$')].tolist() 
print("Ends")
print(colNames_ends)



print("\n")
print("----------------------------------------")
df_subset_start = df.filter(regex='^spike',axis=1)
print("Starts")
print(df_subset_start)



print("\n")
print("----------------------------------------")
df_subset_contains = df.filter(regex='spike',axis=1)
print("Contains")
print(df_subset_contains)



print("\n")
print("----------------------------------------")
df_subset_ends = df.filter(regex='spike$',axis=1)
print("Ends")
print(df_subset_ends)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接