【发布时间】:2021-05-03 22:17:00
【问题描述】:
OBS:我在 SO、Pandas 文档和其他一些网站上搜索了几个小时,但无法理解我的代码在哪里工作。
我的 UDF:
def indice(dfb, lb, ub):
dfb['isOutlier'] = ~dfb['valor_unitario'].between(lb, ub)
dfb = dfb[~dfb.isOutlier]
dfb['indice'] = (dfb['valor_unitario'] - lb) / (ub - lb) * 2000
df = df.astype({'indice': 'int64'})
return dfb
重要:
-
isOutlier列不存在。我现在正在这个函数中创建它。 -
indice列不存在。我现在正在这个函数中创建它。 -
valor_unitario存在并且它是一个浮点数 -
lb和ub是之前定义的 - 此函数在主代码的循环内(但由于 n=0 引发此警告)
发出警告
C:\Users\...\calculoindice_support.py:16: 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
dfb['isOutlier'] = ~dfb['valor_unitario'].between(lb, ub)
我在网上找到了一些文章和问题,而且 StackOverflow 说使用 loc 可以解决问题。我试过了,但没有成功
1º 尝试 - 使用 loc
def indice(dfb, lb, ub):
-> dfb.loc[:,'isOutlier'] = ~dfb['valor_unitario'].between(lb, ub)
dfb = dfb[~dfb.isOutlier]
-> dfb.loc[:,'indice'] = (dfb['valor_unitario'] - lb) / (ub - lb) * 2000
df = df.astype({'indice': 'int64'})
return dfb
我也尝试过每次都使用 loc 其实我尝试了很多可能的组合...尝试在dfb['valor_unitario'] 中使用df.loc 等等 em>
现在我有两次相同的警告,但有点不同:
self._setitem_single_column(ilocs[0], value, pi) 和
self.obj[key] = value
C:\ProgramData\Anaconda3\envs\Indice\lib\site-packages\pandas\core\indexing.py:1676: 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
-> self._setitem_single_column(ilocs[0], value, pi)
和
C:\ProgramData\Anaconda3\envs\Indice\lib\site-packages\pandas\core\indexing.py:1597: 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
-> self.obj[key] = value
我也尝试过使用复制。第一次出现这个警告,简单使用copy() 解决了这个问题,我不知道为什么现在它不起作用(我只是加载了更多数据)
2º 尝试 - 使用 copy()
我尝试将copy()放在三个地方,没有成功
dfb = dfb[~dfb.isOutlier].copy()
dfb['isOutlier'] = ~dfb['valor_unitario'].between(lb, ub).copy()
dfb['isOutlier'] = ~dfb['valor_unitario'].copy().between(lb, ub)
C:\Users\...\calculoindice_support.py:16: 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
dfb['isOutlier'] = ~dfb['valor_unitario'].between(lb, ub)
我没有更多的想法,非常感谢您的支持。
------- Minimun Reproducible Example --------
Main_testing.py
import pandas as pd
import calculoindice_support as indice # module 01
import getitemsid_support as getitems # module 02
df = pd.DataFrame({'loja':[1,4,6,6,4,5,7,8],
'cod_produto':[21,21,21,55,55,43,26,30],
'valor_unitario':[332.21,333.40,333.39,220.40,220.40,104.66,65.00,14.00],
'documento':['324234','434144','532552','524523','524525','423844','529585','239484'],
'empresa':['ABC','ABC','ABC','ABC','ABC','CDE','CDE','CDE']
})
nome_coluna = 'cod_produto'
# getting items id to loop over them
product_ids = getitems.getitemsid(df, nome_coluna)
# initializing main DF with no data
df_nf = pd.DataFrame(columns=list(df.columns.values))
n = 0
while n < len(product_ids):
item = product_ids[n]
df_item = df[df[nome_coluna] == item]
# assigning bounds to each variable
lb, ub = indice.limites(df_item, 10)
# calculating index over DF, using LB and UB
# creating temporary (for each loop) DF
df_nf_aux = indice.indice(df_item, lb, ub)
# assigning temporary DF to main DF that will be exported later
df_nf = pd.concat([df_nf, df_nf_aux],ignore_index=True)
n += 1
calculoindice_support.py(模块 01)
import pandas as pd
def limites(dfa,n):
n_sigma = n * dfa.valor_unitario.std()
mean = dfa.valor_unitario.mean()
lb: float = mean - n_sigma
ub: float = mean + n_sigma
return (lb, ub)
def indice(dfb, lb, ub):
if lb == ub:
dfb.loc[:, 'isOutlier'] = False
dfb.loc[:, 'indice'] = 1
else:
dfb['isOutlier'] = ~dfb['valor_unitario'].between(lb, ub)
dfb = dfb[~dfb.isOutlier]
dfb['indice'] = (dfb['valor_unitario'] - lb) / (ub - lb) * 2000
# df = df.astype({'indice': 'int64'})
return dfb
getitemsid_support.py(模块 02)
def getitemsid(df, coluna):
a = df[coluna].tolist()
return list(set(a))
警告输出:
C:\Users\...\calculoindice_support.py:16: 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
dfb['isOutlier'] = ~dfb['valor_unitario'].between(lb, ub)
C:\ProgramData\Anaconda3\envs\Indice\lib\site-packages\pandas\core\indexing.py:1597: 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
self.obj[key] = value
C:\ProgramData\Anaconda3\envs\Indice\lib\site-packages\pandas\core\indexing.py:1720: 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
self._setitem_single_column(loc, value, pi)
C:\Users\...\calculoindice_support.py:16: 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
dfb['isOutlier'] = ~dfb['valor_unitario'].between(lb, ub)
C:\Users\...\calculoindice_support.py:16: 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
dfb['isOutlier'] = ~dfb['valor_unitario'].between(lb, ub)
【问题讨论】:
-
你的熊猫版本是什么?我无法在 1.2.4 中重现此错误。
-
嗨@Ynjxsjmh,我不太确定,但我认为它是1.1.3。我打开了 Anaconda Prompt,>> Python >> import pandas as pd >> pd.show_versions()。我正在使用带有 Conda 解释器的 PyCharm。感谢您的回复!
-
@Ynjxsjmh,我升级到 1.2.4 并且“警告”不断发生!
-
不知道你想做什么。您可以通过将
indice方法更改为def indice(df, lb, ub)然后添加dfb = df.copy()来修复此警告。
标签: python pandas dataframe indexing warnings