Pandas:合并数据框但对重叠列求和

2024-04-24

我读了很多关于merge() and join()的方法pandas.DataFrames,并在我自己的问题上尝试这些,但没有完全找到解决方案。

我有一个非常大的数据文件 (.csv),其中包含各种 ID 每小时的消耗量。我想汇总每个 ID 每月的消耗量。

由于内存限制,我需要处理每小时消耗文件read_csv分块(使用chunk_size选项),并且最终会在几个月内消耗大量 ID 消耗的 DataFrame,例如:

df1 = 
 Month  Dec  Nov
ID             
XXX    4.0  1.0
YYY    8.0  3.0
ZZZ    4.0  1.0 

df2 = 
 Month  Dec  Nov  Oct
ID                  
AAA    1.0  7.0  9.0
BBB    0.0  NaN  2.0
YYY    5.0  5.0  0.0

为这篇文章生成:

df1 = pd.DataFrame({'ID': ['XXX','XXX','YYY','YYY','ZZZ','ZZZ'], 
                    'Month': ['Nov','Dec']*3, 
                    'Consumption': [1.0,4.0,3.0,8.0,1.0,4.0]})
df1 = df1.pivot(index='ID', columns='Month', values='Consumption')
df2 = pd.DataFrame({'ID': ['AAA','AAA','AAA','YYY','YYY','YYY','BBB','BBB','BBB'], 
                    'Month': ['Oct','Nov','Dec']*3, 
                    'Consumption': [9,7,1,0,5,5,2,np.nan,0]})
df2 = df2.pivot(index='ID', columns='Month', values='Consumption')

请注意,消耗量之间存在差异0.0 and NaN. 0.0意味着至少有一个消耗读数0.0月内,但是NaN表示根本没有记录消耗值,在这种情况下,不能假设为 0。出于我的目的,这种差异必须保持明显。

由于数据文件是以块的形式处理的,因此有些 ID 会出现在多个 DataFrame 中,例如YYY,并且,对于这些 ID,有时月份也会重叠,例如Nov for ID YYY。在此情况下,上半月的消费量为df1下半场是在df2.

因此,为了聚合消耗,我需要按“ID”合并这些 DataFrame,并对重叠的“月份”中的值求和。

直接求和DataFrames 产生许多 NaN:

df1 + df2 = 
 Month   Dec  Nov  Oct
ID                   
AAA     NaN  NaN  NaN
BBB     NaN  NaN  NaN
XXX     NaN  NaN  NaN
YYY    13.0  8.0  NaN
ZZZ     NaN  NaN  NaN

我认为这是因为在汇总 ID/月数时df1没有出现的df2它返回一个 NaN。

外合并生成重叠月份的后缀列:

df1.merge(df2,how='outer',on='ID') = 
 Month  Dec_x  Nov_x  Dec_y  Nov_y  Oct
ID                                    
XXX      4.0    1.0    NaN    NaN  NaN
YYY      8.0    3.0    5.0    5.0  0.0
ZZZ      4.0    1.0    NaN    NaN  NaN
AAA      NaN    NaN    1.0    7.0  9.0
BBB      NaN    NaN    0.0    NaN  2.0

我无法得到combine_first做我想做的事。

我想要的是中间的东西,看起来像这样:

 Month   Dec  Nov  Oct
ID                   
XXX      4.0  1.0  NaN
YYY     13.0  8.0  0.0
ZZZ      4.0  1.0  NaN
AAA      1.0  7.0  9.0
BBB      0.0  NaN  2.0

重叠月份的总和使得x + NaN = x, NaN + y = y and NaN + NaN = NaN.


我看到的一种解决方案是进行合并,然后对重叠的列求和,忽略 NaN:

df3 = df1.merge(df2,how='outer',on='ID',suffixes=['','_x'])
overlapping_months_sufx = df3.columns.values[df3.columns.str.endswith('_x')]
for mnth_sufx in overlapping_months_sufx:
    mnth = mnth_sufx[:-2]
    df3[mnth][df3[mnth_sufx].notnull()] = df3[mnth].fillna(0) + df3[mnth_sufx]
    df3=df3.drop(columns=mnth_sufx)
df3 = 
 Month   Dec  Nov  Oct
ID                   
XXX     4.0  1.0  NaN
YYY    13.0  8.0  0.0
ZZZ     4.0  1.0  NaN
AAA     1.0  7.0  9.0
BBB     0.0  NaN  2.0

考虑到该数据集的大小,如果能有最有效的方法来聚合所有这些数据,那就太好了。有没有更好的方法来做到这一点,也许一步到位?

谢谢, 克里斯


这是一个尝试。如果我理解正确,请发表评论。

Given:

>>> df1                                                                                                                
Month  Dec  Nov
ID             
XXX    4.0  1.0
YYY    8.0  3.0
ZZZ    4.0  1.0
>>> df2                                                                                                                
Month  Dec  Nov  Oct
ID                  
AAA    1.0  7.0  9.0
BBB    0.0  NaN  2.0
YYY    5.0  5.0  0.0

解决方案:

>>> pd.concat([df1, df2]).reset_index().groupby('ID', sort=False).sum(min_count=1)
      Dec  Nov  Oct
ID                 
XXX   4.0  1.0  NaN
YYY  13.0  8.0  0.0
ZZZ   4.0  1.0  NaN
AAA   1.0  7.0  9.0
BBB   0.0  NaN  2.0

解释:

连接只是把df2 under df1.

>>> cat = pd.concat([df1, df2])                                                                                        
>>> cat                                                                                                                
     Dec  Nov  Oct
ID                
XXX  4.0  1.0  NaN
YYY  8.0  3.0  NaN
ZZZ  4.0  1.0  NaN
AAA  1.0  7.0  9.0
BBB  0.0  NaN  2.0
YYY  5.0  5.0  0.0

reset_index将索引移动到列中。

>>> cat = cat.reset_index()                                                                                            
>>> cat                                                                                                                
    ID  Dec  Nov  Oct
0  XXX  4.0  1.0  NaN
1  YYY  8.0  3.0  NaN
2  ZZZ  4.0  1.0  NaN
3  AAA  1.0  7.0  9.0
4  BBB  0.0  NaN  2.0
5  YYY  5.0  5.0  0.0

我这样做是为了有一列名称为'ID'我可以通过它对其他值进行分组。groupby('ID', sort=False)创建共享相同值的行组'ID'列(和sort=False确保最终结果中的行未排序以匹配您的输出)。

我们可以这样检查组大小:

>>> cat.groupby('ID', sort=False).size()                                                                               
ID
XXX    1
YYY    2
ZZZ    1
AAA    1
BBB    1
dtype: int64

正如你所看到的,我们只有一组尺寸为 2 的人,因为'YYY'ID是唯一重复的。

sum(min_count=1)工作原理如下:每组中的值根据其列进行求和。参数min_count=1确保一系列的所有NaN值导致NaN当总结出来的时候。

>>> cat.groupby('ID', sort=False).sum(min_count=1)                                                      
      Dec  Nov  Oct
ID                 
XXX   4.0  1.0  NaN
YYY  13.0  8.0  0.0
ZZZ   4.0  1.0  NaN
AAA   1.0  7.0  9.0
BBB   0.0  NaN  2.0

演示用于min_count:

>>> s = pd.Series([np.nan, np.nan])                                                                                    
>>> s                                                                                                                  
0   NaN
1   NaN
dtype: float64
>>>                                                                                                                    
>>> s.sum()                                                                                                            
0.0
>>> s.sum(min_count=1)                                                                                                 
nan
>>> s[0] = 1                                                                                                           
>>> s                                                                                                                  
0    1.0
1    NaN
dtype: float64
>>> s.sum()                                                                                                            
1.0
>>> s.sum(min_count=1)                                                                                                 
1.0
>>> s.sum(min_count=2)                                                                                                 
nan
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Pandas:合并数据框但对重叠列求和 的相关文章

  • 自 1.4.0 版本以来,sphinx_rtd_theme 不再是硬依赖项

    C Users Administrator Desktop item code serv documents api gt 制作 html 运行 Sphinx v1 6 2 加载腌制环境 失败 无法获取属性 WarningStream
  • winpdb 不适用于 python 3.3

    我无法让 rpdb2 与 python 3 3 一起运行 但根据多个来源 这应该是可能的 rpdb2 d myscript py A password should be set to secure debugger client serv
  • 在Python子目录中创建文件?

    在我的 Python 脚本中 我需要在子目录中创建一个新文件而不更改目录 并且需要从当前目录不断编辑该文件 My code os mkdir datetime dst for ip in open list txt with open ip
  • pandas 使用查询功能检查列是否为空

    我有 pandas 数据框 我想在它的查询函数上执行 isnull 或 not isnull 条件 如下所示 In 67 df data pd DataFrame a 1 20 None 40 50 In 68 df data Out 68
  • Python:合并嵌套列表

    初学者在这里 我有 2 个要合并的嵌套列表 list1 a b c d e f g h list2 p q r s t u v w 我正在寻找的输出是 list3 a p q b c r s d e t f g h u v w 这可以在没有
  • 在 Kivy 应用程序中获取文本输入值

    Python Kivy 新手尝试构建一个测试应用程序 其中包含输入框 确定按钮和单击确定按钮时应更改文本的标签 但我得到了 NameError 全局名称 txt1 未定义 我究竟做错了什么 import Kivy import kivy i
  • Bokeh 相当于 matplotlib 子图

    我正在寻找一种方法来创建包含多个子图的绘图 例如 fig ax0 ax1 plt subplots nrows 2 sharex True 可以在 matplotlib 中完成 然后可以通过以下方式解决ax0 and ax1 有没有办法在
  • Keras AttributeError:“顺序”对象没有属性“predict_classes”

    我试图按照本指南找到模型性能指标 F1 分数 准确性 召回率 https machinelearningmastery com how to calculate precision recall f1 and more for deep l
  • 在 Spark-submit 上的 _find_and_load 中获取文件“”,第 991 行

    我目前使用的是Python 3 7 9 spark spark 2 4 6 bin hadoop2 6 在这个项目 venv 中 我的设置为 kafka python 2 0 2 pip 21 2 4 py4j 0 10 9 pyspark
  • 登录 python + mod_wsgi 应用程序

    我在 apache 服务器上部署了一个 python Flask 应用程序 这是我的abc conf file WSGIDaemonProcess voting app threads 5 WSGIScriptAlias election
  • 如何开始使用“scipy”

    我之前安装过 Python 3 4 2 和 3 5 2 在这两种情况下 我都可以在 Idle 中涉足编写和测试代码 这给了我两个窗口 一个用于代码的 运行 窗口 一个用于交互和测试的 Shell 窗口 输出 抱歉 不确定术语是否正确 现在我
  • 当有效的 django 表单保存在数据库中时如何触发自定义 python 代码

    Django 新手 我创建了一个简单的表单如下this https www youtube com watch v 3XOS UpJirU教程 我的表单正确地将数据保存在我的 Postgres 连接的本地数据库中 我想知道 每当将有效表单保
  • 在pycharm中使用多处理时如何调试

    我正在 pycharm 社区版中使用 anaconda2 调试多进程程序 它有几个后台工作进程 工作进程将检查输入队列以检索任务 而不会休眠 直到收到任务 事实上 我只对主要流程感兴趣 但是pycharm调试器总是单步进入子进程 看起来主进
  • 如何在 Django 中创建多选框?

    我正在尝试创建多选框字段来自姜戈选择 2 https github com applegrew django select2库如下图所示 我使用了下一个代码 但它返回简单的选择多个小部件 我想我忘了补充一些东西 我的错误在哪里 有人可以告诉
  • 是否可以将 SpaCy 安装到 Raspberry Pi 4 Raspbian Buster

    我一整天都在安装 SpaCy sudo pip install U spacy Looking in indexes https pypi org simple https www piwheels org simple Collectin
  • PyCharm 可以列出项目中的所有 Python 错误吗?

    我在虚拟环境中使用 python 2 7 和 PyCharm 2 7 2013 年 2 月 7 日的新版本 每当我打开其中有明确错误的Python文件 相当于其他语言中的编译错误 例如使用未声明的变量 调用不存在的函数 时 它会在文件的装订
  • matplotlib 轴标签偏移量的因素和变化

    在 matplotlib 中的轴刻度标签上 有两种可能的偏移量 factors and shifts 在右下角 1e 8 是一个 因子 1 441249698e1 是一个 移位 这里有很多答案展示了如何操纵两个都 matplotlib 将轴
  • 在 matplotlib 中添加新的导航模式

    我正在编写一个 wx matplotlib 应用程序 并且在向 matplotlib 导航工具栏添加新工具时遇到相当大的困难 基本上我想添加选择工具 选取框 套索等 以切换受控子图的鼠标模式 到目前为止 我还没有找到任何功能可以让我轻松地做
  • 从 C++ 检索 Python 类型

    这个问题实际上是以下两个问题的延伸 如何在 Python 中实现 C 类 以供 C 调用 https stackoverflow com questions 9040669 how can i implement a c class in
  • Python二进制数据读取

    urllib2 请求接收二进制响应 如下所示 00 00 00 01 00 04 41 4D 54 44 00 00 00 00 02 41 97 33 33 41 99 5C 29 41 90 3D 71 41 91 D7 0A 47 0

随机推荐