pandas 如果存在,则删除

vatpfxk5  于 2023-02-11  发布在  其他
关注(0)|答案(6)|浏览(188)

下面的函数接受一个文件并删除列名row_numstart_dateend_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
zaq34kh6

zaq34kh61#

将参数errors添加到DataFrame.drop

错误:{“忽略”,“提高”},默认值为“提高”

如果为“ignore”,则隐藏错误,并且仅删除现有标签。

df = df.drop(['row_num','start_date','end_date','symbol'], axis=1, errors='ignore')

样品

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
jrcvhitl

jrcvhitl2#

只要用Pandas滤镜,Python的方式

奇怪的是,没有答案使用pandas Dataframe filter method

thisFilter = df.filter(drop_list)
df.drop(thisFilter, inplace=True, axis=1)

这将从df中存在的drop_list创建筛选器,然后从axis=1上的dfinplace删除thisFilter

例如,删除与drop_list匹配的列,如果这些列不存在,则不出错

oxcyiej7

oxcyiej73#

在我的测试中,下面的答案至少和给出的任何一个答案一样快:

candidates=['row_num','start_date','end_date','symbol']
df = df.drop([x for x in candidates if x in df.columns], axis=1)

它具有可读性的优点,并且(对代码进行了一点调整)能够准确记录哪些列存在/何时删除。
这可能比先前的解决方案更可取的一些原因是:

  • 循环遍历这些项并单独删除每一列(如果存在)是可行的,但速度相当慢(参见下面的基准测试)。
  • jezrael的回答非常好,但是一开始让我很紧张(忽略错误感觉很糟糕!).进一步查看文档,听起来好像没什么问题,只是忽略了不存在的列的错误(不是其他可能不想忽略的错误).我的解决方案可能更具可读性,特别是对于那些不太熟悉panda中可选kwargs的人.

基准测试结果:

基准测试的代码(this question中给出了如何创建此类基准测试的答案):

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()
zvokhttg

zvokhttg4#

我不得不这么做我是这样做:

# 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)

也许不是最好的方法,但它达到了它的目的。

j7dteeu8

j7dteeu85#

x = ['row_num','start_date','end_date','symbol']

要检查列是否存在,可以执行以下操作:

for i in x:
    if i in df:
        df = df.drop(['row_num','start_date','end_date','symbol'], axis=1).fillna(0)

for i in x:
    if i in df.columns:
        df = df.drop(['row_num','start_date','end_date','symbol'], axis=1).fillna(0)
irtuqstp

irtuqstp6#

使用df.columns.intersection表示速度

df.columns.intersection是一个内置方法,用于排除缺少的列:

existing_cols = df.columns.intersection(["foo", "bar", "baz"])
df = df.drop(columns=existing_cols)

通过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

相关问题