Python *args returns 元组而不是 pandas 数据帧
Python *args returns tuple rather than pandas dataframes
具有return一系列数据帧的功能。
def frames():
bla bla
return df1, df2, df3, df4
我想编写一个函数,将这些帧附加在一起而不必列出计数,这样我以后可以有更多或更少的帧
def appender(*args):
condition goes here
append things that are true
我希望能够这样称呼它
appender(frames())
将return一整帧的帧通过条件。
现在 frames() 函数 return 是一个包含四个帧的元组。是否有任何简单的解决方法来解压元组?
感谢您的帮助!
克莱姆
更新这是一个例子
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 Traceback(最近调用最后)
在 ()
----> 1 个附加程序(帧())
在 appender(*args)
2 main_frame = pd.DataFrame()
3 对于 args 中的 arg:
----> 4 如果 arg.empty != True:
5 assignment_frame = assignment_frame.append(arg)
6
AttributeError: 'tuple' 对象没有属性 'empty'
如果您通过 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
有几个错误:
- 记得在你的初始函数参数中解压。
- 您在
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
in a loop is inefficient due to unnecessary data copying; it's not recommended. A more efficient way of writing this is possible via 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
索引。
具有return一系列数据帧的功能。
def frames():
bla bla
return df1, df2, df3, df4
我想编写一个函数,将这些帧附加在一起而不必列出计数,这样我以后可以有更多或更少的帧
def appender(*args):
condition goes here
append things that are true
我希望能够这样称呼它
appender(frames())
将return一整帧的帧通过条件。
现在 frames() 函数 return 是一个包含四个帧的元组。是否有任何简单的解决方法来解压元组?
感谢您的帮助!
克莱姆
更新这是一个例子
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 Traceback(最近调用最后) 在 () ----> 1 个附加程序(帧())
在 appender(*args) 2 main_frame = pd.DataFrame() 3 对于 args 中的 arg: ----> 4 如果 arg.empty != True: 5 assignment_frame = assignment_frame.append(arg) 6
AttributeError: 'tuple' 对象没有属性 'empty'
如果您通过 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
有几个错误:
- 记得在你的初始函数参数中解压。
- 您在
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
in a loop is inefficient due to unnecessary data copying; it's not recommended. A more efficient way of writing this is possible via 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
索引。