Python df.drop(如果存在)
下面是一个函数,它接受一个文件并删除列名“row_num”、“start_date”、“end_date” 问题是不是每个文件都有这些列名,所以函数返回一个错误 我的目标是修改代码,以便在存在这些列时删除这些列,但在该列不存在时不返回错误Python df.drop(如果存在),python,pandas,Python,Pandas,下面是一个函数,它接受一个文件并删除列名“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
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
将参数
错误
添加到:
错误:{'ignore','raise'},默认为'raise'
如果“忽略”,则抑制错误并仅删除现有标签
样本:
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
要检查列是否存在,可以执行以下操作:
for i in x:
if i in df:
df = df.drop(['row_num','start_date','end_date','symbol'], axis=1).fillna(0)
或
我只是不得不这么做;以下是我所做的:
# Drop these columns if they exist
cols = ['Billing Address Street 1', 'Billing Address Street 2','Billing Company']
for col in cols:
if col in df.columns:
df = df.drop(columns=col, axis=1)
可能不是最好的方法,但它达到了目的。在我的测试中,以下速度至少与给出的任何答案一样快:
candidates=['row_num','start_date','end_date','symbol']
df = df.drop([x for x in candidates if x in df.columns], axis=1)
它具有可读性的优点,并且(对代码进行了一点小的调整)能够准确地记录哪些列在出现时存在/被删除
一些原因可能比以前的解决方案更可取:
- 在项目上循环并单独删除每个列(如果存在的话)是可行的,但速度相当慢(参见下面的基准测试)
- jezrael的回答很好,但一开始让我感到紧张(忽略错误感觉很糟糕!)。进一步查看文档,听起来这似乎没问题,只是忽略了不存在的列的错误(而不是其他不希望忽略的错误)。我的解决方案可能更具可读性,特别是对于那些不太熟悉熊猫中可选Kwarg的人
Try except就是为了这个,我认为你的想法是正确的,但是实现是错误的……你在x中删除了所有内容,如果任何项目在df.columns(不是全部)中,你没有引用x。定义x之后,你应该改为执行
x=[i for i in x if i in df.columns]
,或者使用交集,然后你可以删除x。
for i in x:
if i in df.columns:
df = df.drop(['row_num','start_date','end_date','symbol'], axis=1).fillna(0)
# Drop these columns if they exist
cols = ['Billing Address Street 1', 'Billing Address Street 2','Billing Company']
for col in cols:
if col in df.columns:
df = df.drop(columns=col, axis=1)
candidates=['row_num','start_date','end_date','symbol']
df = df.drop([x for x in candidates if x in df.columns], axis=1)
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()