Python * args返回元组而不是pandas数据帧

时间:2018-10-08 14:47:04

标签: python pandas args

具有一个返回一系列数据帧的函数。

def frames():
  bla bla
  return df1, df2, df3, df4

我想编写一个函数,将这些帧附加在一起而不必列出计数,这样以后我可以有更多或更少的帧

def appender(*args):
   condition goes here
       append things that are true

我希望能够这样称呼

appender(frames())

将返回通过条件的完整帧。

现在,frames()函数返回四个帧的元组。有什么简单的方法可以解开元组吗?

感谢您的帮助!

克莱姆

更新这是一个示例

def frames():

    df1 = pd.DataFrame()

    df2 = pd.DataFrame()

    df3 = pd.DataFrame(['not', 'empty'])

    df4 = pd.DataFrame(['not', 'empty'])

    return df1, df2, df3, df4

def appender(*args):
    main_frame = pd.DataFrame()
    for arg in args:
        if arg.empty != True:
            assignment_frame = assignment_frame.append(arg)

    return assignment_frame


appender(frames())

给予


AttributeError跟踪(最近一次通话)  在()中 ----> 1个appender(frames())

追加器中的

(* args)       2 main_frame = pd.DataFrame()       arg中的arg为3: ----> 4,如果arg.empty!= True:       5 Assignment_frame = assignment_frame.append(arg)       6

AttributeError:“元组”对象没有属性“空”

2 个答案:

答案 0 :(得分:1)

如果您通过appender(*frames())调用原始代码,则可以正常工作,但是由于assignment_frame应该为main_frame,您仍然会收到错误消息。

但是,甚至有一种更简单的方法。只需传递一个数据框集合,然后根据您的条件使用列表推导对其进行过滤即可。

请注意,您不想通过追加来建立数据帧!这称为二次复制,因为每次调用append时,都会返回原始数据帧的副本以及新添加的数据帧。这会变得非常慢。请参见下面的计时。

def appender(dataframes):
    return pd.concat([df for df in dataframes if not df.empty])  # Optional: .reset_index()


>>> appender(frames())
       0
0    not
1  empty
0    not
1  empty

时间(连续或附加)

df = pd.DataFrame(np.random.randn(10, 10))

%timeit df2 = pd.concat([df] * 1000)
# 10 loops, best of 3: 54.7 ms per loop

%%timeit
df3 = pd.DataFrame()
for _ in range(1000):
    df3 = df3.append(df)
# 1 loop, best of 3: 1.28 s per loop

>>> df3.equals(df2)
True

答案 1 :(得分:1)

有两个错误:

  1. 记住要解压缩您的初始函数参数。
  2. 您对appender中数据框的变量名进行了更改,请保持一致。

这是一个可行的示例:

def appender(*args):
    df = pd.DataFrame()
    for arg in args:
        if arg.empty != True:
            df = df.append(arg)
    return df

appender(*frames())

但是pd.DataFrame.append在循环中效率低下,原因是不必要的数据复制;不推荐。可以通过pd.concat和列表理解来更有效地编写此代码:

def appender(*dfs):
    return pd.concat([df for df in dfs if not df.empty], ignore_index=True)

使用ignore_index=True可确保您的输出数据帧具有默认的pd.RangeIndex索引。