首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何将.loc与groupby一起使用,以使基于分组数据创建新列不会被视为副本?

如何将.loc与groupby一起使用,以使基于分组数据创建新列不会被视为副本?
EN

Stack Overflow用户
提问于 2020-07-04 06:12:28
回答 1查看 238关注 0票数 1

我有一个包含数据组的CSV文件,并使用groupby()方法对它们进行分离。每组都通过一些简单的数学运算进行处理,包括对几列使用min()max(),以及一些减法和乘法来创建新的数据列。然后我画出每一组的图表。这在很大程度上可以工作,但我有两个关于我的代码图的抱怨-图是单独的,不是我喜欢的组合;我对每个组都有"SettingWithCopyWarning“。根据我的搜索,我相信解决方案要么是使用.loc,要么是使用更好的split-apply (可能是组合)方法。我可以在Excel中做到这一点,但我正在努力学习Python,当我的代码正常工作时,我想要改进它。

代码语言:javascript
运行
AI代码解释
复制
import os.path
import sys
import pandas as pd

filename = "data/cal_data.csv"
df = pd.read_csv(filename, header=0) #one line of headers

df['Test']="Model "+df['Model No'] +", SN "+ df['Serial No'].values.astype(str) +", Test time "+ df['Test time'].values.astype(str) # combining several columns into a single column that makes grouping straight-forward, and simplifies titles of graphs. Not completely necessary.

df = df[df.index <= df.groupby('Test')['Test Point'].transform('idxmax')]#drop rows after each max test point

for title, group in df.groupby('Test'):
    x1, x2 = min(group["Test Reading"]),max(group["Test Reading"])
    x4, x3 = max(group["Test Point"]),min(group["Test Point"]) #min is usually zero
    R=(x2-x1)/(x4-x3) #linearize
    
    group['Test Point Error']=100*(group['Test Reading']- (group['Test Point']*R+x1))
    
    ax=group.plot(x='Test Point', y='Test Point Error', title=title, grid=True)
    ax.set_ylabel("% error (+/-"+str(Error_Limit)+"% limit)")

输出错误:

代码语言:javascript
运行
AI代码解释
复制
SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy

编辑-添加了来自df.head(20)的输出,以及几个绘图的图像:

代码语言:javascript
运行
AI代码解释
复制
 Test Point Test Reading    Test
0   0   0.10453 Model LC-500, SN 937618, Test time 17:20:10
1   20  0.17271 Model LC-500, SN 937618, Test time 17:20:10
2   50  0.27838 Model LC-500, SN 937618, Test time 17:20:10
3   100 0.45596 Model LC-500, SN 937618, Test time 17:20:10
4   150 0.63435 Model LC-500, SN 937618, Test time 17:20:10
5   200 0.81323 Model LC-500, SN 937618, Test time 17:20:10
6   250 0.99252 Model LC-500, SN 937618, Test time 17:20:10
7   300 1.17222 Model LC-500, SN 937618, Test time 17:20:10
8   350 1.35219 Model LC-500, SN 937618, Test time 17:20:10
9   400 1.53260 Model LC-500, SN 937618, Test time 17:20:10
10  450 1.71312 Model LC-500, SN 937618, Test time 17:20:10
11  500 1.89382 Model LC-500, SN 937618, Test time 17:20:10
14  0   0.10468 Model LC-500, SN 937618, Test time 17:31:46
15  20  0.17284 Model LC-500, SN 937618, Test time 17:31:46
16  50  0.27856 Model LC-500, SN 937618, Test time 17:31:46
17  100 0.45609 Model LC-500, SN 937618, Test time 17:31:46
18  150 0.63457 Model LC-500, SN 937618, Test time 17:31:46
19  200 0.81341 Model LC-500, SN 937618, Test time 17:31:46
20  250 0.99277 Model LC-500, SN 937618, Test time 17:31:46
21  300 1.17237 Model LC-500, SN 937618, Test time 17:31:46

编辑/更新2020年7月23日:我做了几个变通方法,使此工作,但我仍然感谢任何帮助。以下是修改后的for循环代码,将每个组写入一个新的csv文件以供稍后读取(这样我就可以添加在这里创建的新列),如果临时文件已经存在,也将其删除:

代码语言:javascript
运行
AI代码解释
复制
if os.path.exists("data/temp.csv"):
    os.remove("data/temp.csv")
for title, group in df.groupby('Test'):

    x1 = min(group["Test Reading"].head(1))
    x2 = max(group["Test Reading"].tail(1))
    x3 = min(group["Test Point"].head(1))
    x4 = max(group["Test Point"].tail(1))
    R=(x2-x1)/(x4-x3) #linearization scalar
    group['Test Point Error'] =100*(group['Test Reading']- (group['Test Point']*R+x1))/(x2-x1)
    file = open('data/temp.csv','a')
    group.to_csv('data/temp.csv', mode="a", index=False, columns=columns, header=False)#, header=True, index=True, index_label=None, mode='w', encoding=None, compression='infer', quoting=None, quotechar='"', line_terminator=None, chunksize=None, date_format=None, doublequote=True, escapechar=None, decimal='.'))
    file.close()

然后,读取临时csv,我使用seaborn (import seaborn as snsimport matplotlib.pyplot as plt )将多个组绘制在一起,按序列号分组,每行4个子图。

代码语言:javascript
运行
AI代码解释
复制
df = pd.read_csv('data/temp.csv', header=0)
df['Model/SN']=df['Model No']+" / "+df['Serial No'].values.astype(str)
g = sns.FacetGrid(df, col='Model/SN', hue='Test', col_wrap=4, sharey=False, sharex=False)

g.map(plt.axhline, y=Error_Limit, ls='--', c='red')
g.map(plt.axhline, y=-Error_Limit, ls='--', c='red')

g = g.map(sns.lineplot, 'Test Point', 'Test Point Error', ci=None)

总而言之-这些修复并不理想;它们是变通的解决方案,我仍然收到"SettingWithCopyWarning“错误。

EN

回答 1

Stack Overflow用户

发布于 2020-07-24 15:32:45

所以你的要求是:

  1. 如何停止为副本设置值。
  2. 如何在matplotlib中创建具有每个组的子图的图。

之所以会出现"SettingWithCopyWarning“,是因为您正在创建一列并在每个组上设置值,这本身就是DataFrame的某些行的副本。我不是在每个循环上设置值,而是在退出for循环后将“Test_Point_Error”存储在序列和pd.concat(list)的列表中,然后将其添加到DF中。

-编辑-尝试替换:

代码语言:javascript
运行
AI代码解释
复制
group['Test Point Error']=100*(group['Test Reading']- (group['Test Point']*R+x1))

使用

代码语言:javascript
运行
AI代码解释
复制
error_list.append(100 * (group['Test Reading']- (group['Test Point']*R+x1)))

因此,在退出for-loop之后:

代码语言:javascript
运行
AI代码解释
复制
df.assign(test_point_error=pd.concat(error_list))

-编辑结束

如果您在退出for-loop之后绘制,那么

代码语言:javascript
运行
AI代码解释
复制
df.groupby().plot(subplots=True)

将返回您想要的内容。

在另一个主题中,我将去掉'Test‘的字符串连接,而是这样做:

代码语言:javascript
运行
AI代码解释
复制
df.groupby(['Model No', 'Serial No', 'Test Time'])

如果有很多行,这可能会使您的代码更快。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62725942

复制
相关文章
Nginx重新编译添加模块
找到安装nginx的源码根目录,如果没有的话下载新的源码 http://nginx.org tar xvzf nginx-1.3.2.tar.gz 查看ngixn版本极其编译参数 /usr/local/nginx/sbin/nginx -V 进入nginx源码目录 cd nginx-1.3.2 以下是重新编译的代码和模块 ./configure --prefix=/usr/local/nginx--with-http_stub_status_module --with-http_ssl_module --w
CrazyCodes
2019/11/07
1.6K0
不重新编译PHP,单独添加扩展模块的方法
php自身提供了很多扩展,比如curl,gmp, mbstring等等。我们在编译安装php时未必安装了所有扩展。那么在安装完php后,如果想单独安装某个php自身的扩展怎么办呢?
跑马溜溜的球
2020/12/07
1.6K0
JS操作对象属性(获取、添加、删除、修改对象属性)
属性也称为名值对,包括属性名和属性值。属性名可以是包含空字符串在内的任意字符串,一个对象中不能存在两个同名的属性。属性值可以是任意类型的数据。
用户7741497
2022/03/19
16.6K0
Vue删除对象属性需要注意的地方
上面的一段代码是我们使用Vue时常用的,这样remarks就成为创建的Vue对象的一个属性,如果我们要添加Vue属性可以通过set方法:
johnhuster的分享
2022/03/28
9520
hadoop重新编译
yum -y install  lzo-devel  zlib-devel  gcc autoconf automake libtool gcc-c++ openssl-devel ncurses-devel    
Dlimeng
2023/06/28
1890
重新编译mondrian
private synchronized ObjectPool getPool(Object key, ConnectionFactory connectionFactory) {
Dlimeng
2023/06/29
1670
CUDA跟OpenCV的混合编程,注意OpenCV需要重新编译
http://blog.csdn.net/wangyaninglm/article/details/39997113
流川疯
2022/11/29
4210
CUDA跟OpenCV的混合编程,注意OpenCV需要重新编译
apktool重新打包添加签名
一.生成apk apktool b 反编译后项目目录 -o 新apk名称.apk 二.生成签名 keytool -genkeypair -alias 新apk名称.apk -keyalg RSA -validity 100 -keystore app.keystore #拓展 -genkey 生成秘钥 -alias 别名 -keyalg 秘钥算法 -keysize 秘钥长度 -validity 有效期 -keystore 生成秘钥库的存储路径和名称 -keypass 秘钥口令 -storep
小小咸鱼YwY
2020/07/01
7430
QListWidget添加删除
qt和vc一样自由线程模式,线程间可以访问ui,但线程间访问qt内部封装问题,导致很多一样,可以使用信号和槽线程间传递数据,避免异常
sofu456
2020/08/11
1K0
Array对象---添加或删除数组中的元素->splice()
定义: splice() 方法用于添加或删除数组中的元素。(会修改原始数据) 参数说明: array.splice(index,howmany,item1,.....,itemX) 1、index 必需。规定从何处添加/删除元素。 该参数是开始插入和(或)删除的数组元素的下标,必须是数字。(从0开始) 2、howmany 可选。规定应该删除多少元素。必须是数字,但可以是 "0"。 如果未规定此参数,则删除从 index 开始到原数组结尾的所有元素。 3、item1, ..., itemX 可选。要添加
听着music睡
2021/11/02
3.7K0
Hadoop-2.2.0在Unbuntu ADM64中需要重新编译Native Lib
通过:cat /etc/issue 查看当前系统版本: Ubuntu 12.04.3
星哥玩云
2022/06/29
3630
Fragment添加、删除、替换
前面一起学习了Fragment的创建和加载,以及其生命周期方法,那么接下来进一步来学习Fragment的具体使用,本期先来学习Fragment添加、删除、替换。 一、概述 在前面的学习中,特别是动态加载的时候,有提到FragmentManager和FragmentTransaction类,这里先来详细了解一下其到底为何物。 01FragmentManager 要管理Activity中的Fragments,就需要使用FragmentManager类。通过getFragmentMana
分享达人秀
2018/02/05
11.6K0
Fragment添加、删除、替换
13,Matplotlib面向对象绘图
Matplotlib是Python数据分析中用于数据可视化的最著名的一个库,其绘图方式和matlab中的绘图方式非常相似。
lyhue1991
2020/07/20
1.1K0
R语言绘图中添加公式
R语言在作图时难免会用到公式,往途中添加标签公式的方法有很多,R基础包自带的expression函数就是一个,除此之外还有latex2exp可以在R语言中使用latex的命令来给图片添加公式。本文基于expression函数常用的命令从常用的运算符、大型运算、集合运算、希腊字母等方面给出常用的公式命令。
拴小林
2021/10/11
2K0
R语言绘图中添加公式
jQuery实现动态添加和删除(点击按钮添加在页面添加和删除元素)
1:点击添加按钮弹出弹框,form表单可以填写相关的信息 2:点击保存按钮,相关信息会显示在界面的列表里
王小婷
2019/02/26
7.4K0
为什么不需要为Python对象添加 getter 和 setter
Getter 和 setter在java中被广泛使用。一个好的java编程准则为:将所有属性设置为私有的,同时为属性写getter和setter函数以供外部使用。 这样做的好处是属性的具体实现被隐藏,当未来需要修改时,只需要修改getter 和 setter即可,而不用修改代码中所有引用这个属性的地方。可能做的修改为: 在获取或设置属性时打一条日志 设置属性时,对值对进检查 设置发生时, 修改设置的值 获取属性时,动态地计算值 可谓是好处多多,getter和setter为变量访问提供了灵活的方式。 但pyt
用户2176428
2018/06/27
1.3K0
mysql 查看索引、添加索引、删除索引命令添加索引删除索引
· Table 表的名称。 · Non_unique 如果索引不能包括重复词,则为0。如果可以,则为1。 · Key_name 索引的名称。 · Seq_in_index 索引中的列序列号,从1开始。 · Column_name 列名称。 · Collation 列以什么方式存储在索引中。在MySQL中,有值‘A’(升序)或NULL(无分类)。 · Cardinality 索引中唯一值的数目的估计值。通过运行ANALYZE TABLE或myisamchk -a可以更新。基数根据被存储为整数的统计数据来计数,所以即使对于小型表,该值也没有必要是精确的。基数越大,当进行联合时,MySQL使用该索引的机 会就越大。 · Sub_part 如果列只是被部分地编入索引,则为被编入索引的字符的数目。如果整列被编入索引,则为NULL。 · Packed 指示关键字如何被压缩。如果没有被压缩,则为NULL。 · Null 如果列含有NULL,则含有YES。如果没有,则该列含有NO。 · Index_type 用过的索引方法(BTREE, FULLTEXT, HASH, RTREE)。 · Comment
一个会写诗的程序员
2018/08/17
3.5K0
tcsetpgrp failed重新编译tini
因为本人在腾讯,这是因为开发环境的 tlinux 的问题,导致 tini 出错了。寻找了很久,也没找到 特别有效的信息,于是查看一下 tini 的源码,看看 这个 错误是如何产生的。
runzhliu
2020/08/06
1.2K0
svn如何删除当前账号,重新登录
今天需要从svn上拉取工程,可是无论如何都显示我没有权限.思索半天才发现,我在eclipse填上远程链接后为什么没有提示我要输入账号和密码呢?原来我用的笔记本是之前公司别人用的,因此svn一定是记住了
全栈程序员站长
2022/06/30
2.3K0
svn如何删除当前账号,重新登录
点击加载更多

相似问题

如何在MYSQL中获得两个datetimes之间的差异?

50

如何在Server中获得两个日期之间的秒数?

46

如何在javascript中获得两个日期之间的秒数?

20

计算两个XQuery之间的秒数的dateTimes表达式是什么?

12

如何在Oracle中查找两个datetimes之间的差异

12
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文