需求:数据在后缀为xlsx的Excel的sheet1中且量比较大,比如几十万行几百列;想查找一个关键字所在的行,比如"全网首发";
情况①知道关键字在哪一列
情况②不确定在哪一列,很多列相似又不同,本文演示遍历所有数据,但做点优化避免浪费时间性能;
关键字可能是一串数字,日志的部分内容,加密的某一段等
Excel实现和python实现;
数据大概这样子,这纯粹是我瞎编的简单演示数据,假设关键字为中文,商品全称、简称、特点列会造成查找重复:
1.知道关键字在哪一列
比如关键字在 商品简称 这一列!
1.1excel多种实现和比较
①直接用筛选,包含,推荐!
②超级表ctrl+T,小数据可以这样,数据多不推荐,就是将表本身的数据变成了插入的表格,超级表的筛选功能貌似更强,但数据一多,超级表会很卡;
③用Excel本身的函数:不推荐,麻烦不好用,比如关键字是 猛火
函数嵌套大致这样:
先在sheet2中,弄一个辅助列(本文是演示,其实可以将辅助列的结果包在函数中),用函数判断,这对锁行、列号和excel的公式功底有一定的要求;
find("查找关键字","哪个单元格")-->找到返回起始位置,没有返回错误;
辅助列中,找商品简称列,有没有包含猛火;可以看到辅助列,3和4就是sheet1中商品简称那一列有;
再叠加if,如果辅助列不是错误,就用index返回sheet1中对应数据,都需要往右边推一列,因为辅助列占了一个位置,或者其他函数,大概就是先这样,再那样,就行啦。
然后定位,错误,删掉,但我们的数据是很大的,而且excel的函数但凡写多点就令人窒息。
④power query、VBA、数据透视表,一般用这些稍微复杂点的方法,那肯定是经常做这些方面的工作,基本懂的都会用,本文主讲临时需求,简单高效干完就擦屁股完事。
1.2python多种实现和比较
读写文件用pandas库为例
①用索引
df[df["商品全称"].str.contains('纯铜')]
②用query语法
一种类似与SQL但又不完全是的语法, 很多时候query能方便地解决很麻烦的事;
df.query('商品全称.str.contains("台式")')
③自写函数,强行搞
例如,我们知道这个关键字,必然在“商品简称”之中:
import pandas as pd
path = "d:/test.xlsx"
df = pd.read_excel(path)
row_list= [] # 存符合条件的行号
for index_num in df.index:
data = df.loc[index_num,"商品简称"]
if data.find("家用")!=-1:
print(data)
row_list.append(index_num)
print(row_list)
find方法,找到了返回关键字在str中起始位置,找不到返回-1;
此时不能用str.contains方法,因为str.contains前面的东西,最起码得是个series,我写的这个只是一个单纯的单元格内的数据,同时避免了用正则,运行效率upupup。
2.假如列很多,根本就不知道关键字在哪一列
此时excel就很蛋疼了,感觉应该可以,但是并不想去弄。
python多种实现:
2.1如果条件必须是多个列同时包含,而且列不太多
手写一下,索引和query搞定,当然将&变成|, and 变成or ,条件变为 或;
①用索引
df[df["商品全称"].str.contains('液化气') & df["商品简称"].str.contains('液化')]
②用query
df.query('商品全称.str.contains("液化气") and 商品简称.str.contains("台式")')
2.2 某一列包含某个关键字,列很多,不知道哪一列
本文的演示数据太简单,比如有很多列,只要哪一列有符合条件的,整列都要,但是列非常多,总不能手写吧;
此时能想到的方法是:遍历数据硬来;
可以自写方法,iloc或者loc,根据数据类型从行、列df.index,df.columns遍历都行;
推荐使用一个函数iterrows(),返回df的行索引和df每一个行数据,注意是行数据series类型;
row_list= []
for row_index,row_data in df.iterrows():
try:
for col in df.columns:
cell_data = df.loc[row_index,col]
# if str(row_data[col]).find("猛火")!=-1:
if str(cell_data).find("猛火")!=-1:
row_list.append(row_index)
raise ValueError("已找到条件")
except:
pass
print(row_list)
①为什么要用try,except?
因为我们要的数据是整个行,只要其中某一列符合条件,整行都要。但凡哪一列找到了关键字,结果存到list中,直接报个错,避免了往后面的列遍历的无用功,比set去重好;
②注意要str(cell_data),因为时间列这种东西,总会出点小问题;