具有一个返回一系列数据帧的函数。
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:“元组”对象没有属性“空”
答案 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)
有两个错误:
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
索引。