下面是一个函数,它接受一个文件并删除列名“row_num”、“start_date”、“end_date”。
问题是不是每个文件都有这些列名,所以函数返回一个错误。
我的目标是更改代码,以便在这些列存在时删除这些列,但如果该列不存在则不返回错误。
def read_df(file):
df = pd.read_csv(file, na_values=['', ' '])
# Drop useless junk and fill empty values with zero
df = df.drop(['row_num','start_date','end_date','symbol'], axis=1).fillna(0)
df=df[df!=0][:-1].dropna().append(df.iloc[-1])
return df
Run Code Online (Sandbox Code Playgroud)
jez*_*ael 102
将参数添加errors到DataFrame.drop:
错误:{'ignore', 'raise'},默认为 'raise'
如果为“忽略”,则抑制错误并仅删除现有标签。
df = df.drop(['row_num','start_date','end_date','symbol'], axis=1, errors='ignore')
Run Code Online (Sandbox Code Playgroud)
样品:
df = pd.DataFrame({'row_num':[1,2], 'w':[3,4]})
df = df.drop(['row_num','start_date','end_date','symbol'], axis=1, errors='ignore')
print (df)
w
0 3
1 4
Run Code Online (Sandbox Code Playgroud)
Tim*_*art 31
奇怪的是,没有答案使用pandas数据框filter method
thisFilter = df.filter(drop_list)
df.drop(thisFilter, inplace=True, axis=1)
Run Code Online (Sandbox Code Playgroud)
drop_list这将从中创建一个过滤器df,然后thisFilter从df inplace中删除axis=1
即,删除与 匹配的列drop_list,如果它们不存在也不会出错
tdy*_*tdy 11
df.columns.intersection速度df.columns.intersection是排除缺失列的内置方法:
existing_cols = df.columns.intersection(["foo", "bar", "baz"])
df = df.drop(columns=existing_cols)
Run Code Online (Sandbox Code Playgroud)
即使缺失列的数量不断增加,删除 via 的速度df.columns.intersection也非常快:
计时数据:
df = pd.DataFrame(np.random.random((10_000, 200)), columns=range(-200, 0))
cols = range(-100, n) # 100 dropped columns, n missing columns
Run Code Online (Sandbox Code Playgroud)
在我的测试中,以下内容至少与任何给定答案一样快:
candidates=['row_num','start_date','end_date','symbol']
df = df.drop([x for x in candidates if x in df.columns], axis=1)
Run Code Online (Sandbox Code Playgroud)
它具有可读性的优点,并且(通过对代码进行小幅调整)能够准确记录哪些列在何时存在/被删除。
这可能比以前的解决方案更可取的一些原因:
基准测试结果:
基准测试代码(归功于此问题中有关如何创建此类基准的答案):
import math
from simple_benchmark import benchmark
import pandas as pd
# setting up the toy df:
def df_creator(length):
c1=list(range(0,10))
c2=list('a,b,c,d,e'.split(','))
c3=list(range(0,5))
c4=[True,False]
lists=[c1,c2,c3,c4]
df=pd.DataFrame()
count=0
for x in lists:
count+=1
df['col'+str(count)]=x*math.floor(length/len(x))
return df
# setting up benchmark test:
def list_comp(df,candidates=['col1','col2','col5','col8']):
return df.drop([x for x in candidates if x in df.columns], axis=1)
def looper(df,candidates=['col1','col2','col5','col8']):
for col in candidates:
if col in df.columns:
out = df.drop(columns=col, axis=1)
return out
def ignore_error(df,candidates=['col1','col2','col5','col8']):
return df.drop(candidates, axis=1, errors='ignore')
functions=[list_comp,looper,ignore_error]
args={n : df_creator(n) for n in [10,100,1000,10000,100000]}
argname='df_length'
b=benchmark(functions,args,argname)
b.plot()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
26038 次 |
| 最近记录: |