【问题标题】:Inplace Modifying a Column in a DataFrame就地修改 DataFrame 中的列
【发布时间】:2019-11-10 05:13:54
【问题描述】:

编辑:我已经意识到,当使用 .loc 访问时,我没有收到任何错误,而是一个警告,所以代码确实有效。

我有一个需要清理的数据集。我需要做的一件事是删除所有超过 50000kn 的交易。 碰巧成本bruto_prihod 是字符串格式,事务transakcija_sifra 跨越多行。 另一个不便之处是十进制格式使用逗号(我们在克罗地亚语中使用十进制逗号)而不是点。

这是我在任务之前的代码:

    import pandas as pd
    import numpy as np

    diversus = pd.read_csv(r"C:\Users\dagejev\Desktop\excel\diversus4_saved.csv", encoding="cp1252", sep=";")

    df = diversus.copy()

    df_filter = df[(df['faza'] == 'A') &
                   ( (df['grupa_id'] == 'W ODIJELO') | (df['grupa_id'] == 'ODIJELO') ) &
                   ( (df['vp_kupac_id']!= 591) & (df['vp_kupac_id']!= 333) & (df['vp_kupac_id']!= 332) ) &
                   ( (df['brand_naziv'] == 'JOOP') | (df['brand_naziv'] == 'JOOP!') ) &
                   (df['vrsta_robe']=='ROBA') &
                   (df['divizija'] == 'MEN')]
    print('df: ', len(df), 'filtered: ', len(df_filter))

以下是相关部分:

#This is what I tried first

df_filter['bruto_prihod'] = df_filter['bruto_prihod'].str.replace(',','.')

但是,它不起作用:

C:\Users\dagejev\AppData\Local\Continuum\anaconda3\lib\site-packages\ipykernel_launcher.py:1: 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: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  """Entry point for launching an IPython kernel.

建议的替代方案也没有:

    df_filter[:,'bruto_prihod'] = df_filter['bruto_prihod'].str.replace(',','.')

    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-82-0e27bdc0e78f> in <module>
    ----> 1 df_filter[:,'bruto_prihod'] = df_filter['bruto_prihod'].str.replace(',','.')

    ~\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\frame.py in __setitem__(self, key, value)
       3368         else:
       3369             # set column
    -> 3370             self._set_item(key, value)
       3371 
       3372     def _setitem_slice(self, key, value):

    ~\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\frame.py in _set_item(self, key, value)
       3443 
       3444         self._ensure_valid_index(value)
    -> 3445         value = self._sanitize_column(key, value)
       3446         NDFrame._set_item(self, key, value)
       3447 

    ~\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\frame.py in _sanitize_column(self, key, value, broadcast)
       3659 
       3660         # broadcast across multiple columns if necessary
    -> 3661         if broadcast and key in self.columns and value.ndim == 1:
       3662             if (not self.columns.is_unique or
       3663                     isinstance(self.columns, MultiIndex)):

    ~\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\indexes\base.py in __contains__(self, key)
       3918     @Appender(_index_shared_docs['contains'] % _index_doc_kwargs)
       3919     def __contains__(self, key):
    -> 3920         hash(key)
       3921         try:
       3922             return key in self._engine

    TypeError: unhashable type: 'slice'

但是这个链索引确实 (which is supposedly always bad to use):

    df_filter[:]['bruto_prihod'] = df_filter['bruto_prihod'].str.replace(',','.')

此外,这不起作用:

    df_filter['bruto_prihod'] = pd.to_numeric(df_filter['bruto_prihod'])

但这确实:

df_filter[:]['bruto_prihod'] = pd.to_numeric(df_filter['bruto_prihod'])

为什么会这样? 为什么我必须为我的就地分配工作链接索引?

另外,如果有人感兴趣,这就是我对交易进行分组的方式:

df_filter.groupby('transakcija_sifra').agg({'bruto_prihod':np.sum}).sort_values('bruto_prihod', ascending=False)

【问题讨论】:

  • 使用 .loc 而不是链接:df_filter.loc[:, 'bruto_prihod'] = df_filter.loc[:, 'bruto_prihod'].str.replace(',','.')。但它应该在没有链接或.loc 的情况下工作,这很奇怪。不起作用是什么意思,是否收到错误消息?
  • 已经尝试过了,错误如下:C:\Users\dagejev\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\indexing.py:543: SettingWithCopyWarning: A value正在尝试在 DataFrame 中的切片副本上设置。尝试改用 .loc[row_indexer,col_indexer] = value
  • @Dan 是的,我的意思是我收到了一条错误消息,因为不起作用。
  • 请始终在您的问题中包含确切的错误消息。另外你什么时候做groupby?在此错误之前还是之后?您是否将分组系列分配到某个地方?
  • @Dan 我正在做groupby 在其他所有事情之后。链接索引时没有错误。我将去编辑答案以包含错误。我目前只是查看groupby

标签: python pandas data-science


【解决方案1】:

为了避免警告,您可以使用明确的copy

df_filter = df[(df['faza'] == 'A') &
               ( (df['grupa_id'] == 'W ODIJELO') | (df['grupa_id'] == 'ODIJELO') ) &
               ( (df['vp_kupac_id']!= 591) & (df['vp_kupac_id']!= 333) & (df['vp_kupac_id']!= 332) ) &
               ( (df['brand_naziv'] == 'JOOP') | (df['brand_naziv'] == 'JOOP!') ) &
               (df['vrsta_robe']=='ROBA') &
               (df['divizija'] == 'MEN')].copy()

【讨论】:

  • 谢谢。这看起来像是更好的代码,但我没有收到任何警告。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-11
  • 1970-01-01
  • 2014-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多