如何根据部分匹配选择 DataFrame 列?
Posted
技术标签:
【中文标题】如何根据部分匹配选择 DataFrame 列?【英文标题】:How to select DataFrame columns based on partial matching? 【发布时间】:2015-10-11 15:16:49 【问题描述】:今天下午我正在努力寻找一种方法来选择我的 Pandas DataFrame 的几列,方法是检查它们名称(标签?)中出现的特定模式。
我一直在为nd.arrays
/ pd.series
寻找类似contains
或isin
的东西,但没有成功。
这让我很沮丧,因为我已经在检查 DataFrame
的列中是否出现了特定的字符串模式,例如:
hp = ~(df.target_column.str.contains('some_text') | df.target_column.str.contains('other_text'))
df_cln= df[hp]
但是,无论我怎么敲头,我都无法将.str.contains()
应用于df.columns
返回的对象——这是一个Index
——也不是df.columns.values
返回的对象——这是一个@987654331 @。不过,这对于“切片”操作df[column_name]
(即Series
)返回的内容很有效。
我的第一个解决方案涉及for
循环和帮助列表的创建:
ll = []
for a in df.columns:
if a.startswith('start_exp1') | a.startswith('start_exp2'):
ll.append(a)
df[ll]
(当然可以应用任何str
函数)
然后,我找到了map
函数并让它与以下代码一起工作:
import re
sel = df.columns.map(lambda x: bool(re.search('your_regex',x))
df[df.columns[sel]]
当然,在第一个解决方案中,我可以执行相同类型的正则表达式检查,因为我可以将其应用于迭代返回的 str
数据类型。
我对 Python 很陌生,从来没有真正编程过任何东西,所以我对速度/时间/效率不太熟悉,但我倾向于认为第二种方法 - 使用地图 - 除了看起来更优雅之外,可能会更快对我未经训练的眼睛。
我很想知道您对此有何看法,以及可能的替代方案。鉴于我的菜鸟水平,如果您能纠正我在代码中可能犯的任何错误并指出正确的方向,我将不胜感激。
谢谢, 米歇尔
编辑:我刚刚找到了 Index
方法 Index.to_series()
,它返回 - ehm - 我可以应用 .str.contains('whatever')
的 Series
。
但是,这不如真正的正则表达式强大,而且我找不到将Index.to_series().str
的结果传递给re.search()
函数的方法..
【问题讨论】:
注:系列过滤器支持正则表达式 【参考方案1】:通过部分字符串选择列,可以简单地通过:
df.filter(like='hello') # select columns which contain the word hello
并且要通过部分字符串匹配来选择行,您可以将axis=0传递给过滤器:
df.filter(like='hello', axis=0)
【讨论】:
【参考方案2】:您使用map
的解决方案非常好。如果您真的想使用 str.contains,可以将 Index 对象转换为 Series(具有 str.contains
方法):
In [1]: df
Out[1]:
x y z
0 0 0 0
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4
5 5 5 5
6 6 6 6
7 7 7 7
8 8 8 8
9 9 9 9
In [2]: df.columns.to_series().str.contains('x')
Out[2]:
x True
y False
z False
dtype: bool
In [3]: df[df.columns[df.columns.to_series().str.contains('x')]]
Out[3]:
x
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
更新我刚刚读了你的最后一段。从documentation,str.contains
允许您默认传递正则表达式 (str.contains('^myregex')
)
【讨论】:
只要df.loc[:, df.columns.str.contains('x')]
也可以。
@Robert Smith 更新是最有用的。我对它进行了更多研究,发现了两件事。设置case=False
进行不区分大小写的搜索,设置regex=True
使用正则表达式。示例:df.loc[:, df.columns.str.contains('x', case=False, regex=True)]
【参考方案3】:
我认为df.keys().tolist()
是您正在寻找的东西。
A tiny example:
from pandas import DataFrame as df
d = df('somename': [1,2,3], 'othername': [4,5,6])
names = d.keys().tolist()
for n in names:
print n
print type(n)
输出:
othername
type 'str'
somename
type 'str'
然后用你得到的字符串,你可以做任何你想要的字符串操作。
【讨论】:
以上是关于如何根据部分匹配选择 DataFrame 列?的主要内容,如果未能解决你的问题,请参考以下文章
如何根据另一列的值从 Spark DataFrame 中选择特定列?