惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
DataBreaches.Net
J
Java Code Geeks
有赞技术团队
有赞技术团队
H
Hackread – Cybersecurity News, Data Breaches, AI and More
The GitHub Blog
The GitHub Blog
T
The Blog of Author Tim Ferriss
Apple Machine Learning Research
Apple Machine Learning Research
量子位
D
Docker
V
Visual Studio Blog
博客园 - 司徒正美
Martin Fowler
Martin Fowler
人人都是产品经理
人人都是产品经理
WordPress大学
WordPress大学
U
Unit 42
M
MIT News - Artificial intelligence
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
G
Google Developers Blog
Engineering at Meta
Engineering at Meta
V
V2EX
大猫的无限游戏
大猫的无限游戏
雷峰网
雷峰网
Vercel News
Vercel News
C
Check Point Blog

阿猪的博客

如何使用CNB构建Hexo项目并部署到腾讯云COS 好坑爹!派息后买入的股票怎么也扣股息税? 游哈尔滨 跨年往事 安装Ta-Lib时报错"Could not build wheels" 网站被恶意镜像了该怎么办 延迟退休正式到来!来看看有什么规定 我的基金怎么就被强制卖出了? Hexo-AlgoliaSearch插件报错“Error has occurred during indexing posts” 找工作避坑不完全指南 办理信用卡应该注意什么 华为Pad开启了“共享至电脑”,但是Windows下无法正常访问 webdriver-manager报错一例 Windows无法从环境变量中找到Python的正确位置 习大大2024年新年贺词 号外!号外!Twikoo可以直接屏蔽垃圾评论啦! 如何将Coding的代码仓同步到Github 博客被攻击了 华为Pad开启了“共享至电脑”,但是Ubuntu下无法正常访问 如何恢复Etcher刻录过的U盘 如何在Ubuntu下快速切换网络代理状态 在腾讯云函数中使用Pandas报错`No module named 'numpy.core._multiarray_umath'` SQLite中使用关键字作为列名称导致报错 Logging模块重复输出内容的原因及解决方法 如何在Selenium中保持网站的登录状态 如何下载与Chrome浏览器的版本相匹配的ChromeDriver 如何下载旧版本Python的安装包 如何为不同的Python项目自动选择不同的解释器 使用腾讯云函数搭建Web站点 WordPress CORS问题一例
对空的DataFrame使用apply方法未得到预期结果
阿猪 · 2023-12-03 · via 阿猪的博客

一、问题及原因

  阿猪希望使用Pandas的apply方法对原先的DataFrame进行运算从而得到一个新的DataFrame,新的DataFrame与原先的DataFrame拥有不同的列。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import pandas

df = pandas.DataFrame({
'a': [1, 2, 3, 4, 5],
'b': [10, 20, 30, 40, 50],
'c': [50, 60, 70, 80, 90]
})

def func(row):
return pandas.Series({'d': row['a'], 'e': row['b'] + row['c']})

df_new = df.apply(func, axis=1)
df_new = df_new.reset_index(drop=True)

print(df_new)

  上边的示例代码是一个简化后的原型,它会创建一个新的DataFramedf_new,拥有两个新的列de,其中d列与原DataFramedfa列相同,e列则由dfb列和c相加而得。

  当df不为空时,可以得到预期的结果:

1
2
3
4
5
6
   d    e
0 1 60
1 2 80
2 3 100
3 4 120
4 5 140

  但是当将df的值改为pandas.DataFrame(columns = ['a', 'b', 'c'])时(即定义了列的空DataFrame),运行代码后返回的结果并不是预期的

Empty DataFrame
Columns: [d, e]
Index: []

  而是直接返回了df的值:

Empty DataFrame
Columns: [a, b, c]
Index: []

  经过网上一番搜索和调试,原来问题出在apply方法处理空DataFrame的逻辑上。当对df使用apply方法时,Pandas会调用pandas.core.apply.frame_apply

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class FrameApply(NDFrameApply):
# 此处省略N行代码

def apply(self) -> DataFrame | Series:
# 此处省略N行代码

# all empty
if len(self.columns) == 0 and len(self.index) == 0:
return self.apply_empty_result()

# 此处省略N行代码

# one axis empty
elif not all(self.obj.shape):
return self.apply_empty_result()

  这里会对df的行和列进行检查。如果df的行或/和列为空,则不会继续运行后续的代码,而是直接返回apply_empty_result的结果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class FrameApply(NDFrameApply):
# 此处省略N行代码

def apply_empty_result(self):

# 此处省略N行代码

if self.result_type not in ["reduce", None]:
return self.obj.copy()

# we may need to infer
should_reduce = self.result_type == "reduce"

# 此处省略N行代码

if should_reduce:

# 此处省略N行代码

else:
return self.obj.copy()

  在apply_empty_result中,如果apply的result_type参数的值不是reduce或者默认值None,则会直接复制df并返回,从而导致运行示例代码后直接返回了df的值。

二、解决方法

1、在使用apply方法之前进行条件判断

  示例代码如下:

1
2
3
4
5
if len(df) == 0:
df_new = pandas.DataFrame(columns = ['d', 'e'])
else:
df_new = df.apply(func, axis=1)
df_new = df_new.reset_index(drop=True)

2、在返回的结果中修改列索引

  示例代码如下:

1
2
df_new = df.apply(func, axis=1)
df_new = df_new.reindex(columns=['d', 'e'])

版权声明: 未经书面授权许可,任何个人和组织不得以任何形式转载、引用本站的任何内容。本站保留追究侵权者法律责任的权利。

赏杯咖啡,鼓励一下~

  • 微信打赏

    微信打赏