UserWarning:Pandas不允许通过新的属性名称创建列

问题描述 投票:8回答:4

我被困在我的熊猫脚本中。

实际上,我正在使用两个csv文件(一个输入和另一个输出文件)。我想复制两列的所有行,并希望进行计算,然后将其复制到另一个数据帧(输出文件)。

列如下:

'lat', 'long','PHCount', 'latOffset_1', 'longOffset_1','PH_Lat_1', 'PH_Long_1', 'latOffset_2', 'longOffset_2', 'PH_Lat_2', 'PH_Long_2', 'latOffset_3', 'longOffset_3','PH_Lat_3', 'PH_Long_3',  'latOffset_4', 'longOffset_4','PH_Lat_4', 'PH_Long_4'.

我想把列'lat'和'latOffset_1',做一些计算并把它放在我已经创建的另一个新列('PH_Lat_1')中。

我的功能是:

def calculate_latoffset(latoffset):  #Calculating Lat offset.
    a=(df2['lat']-(2*latoffset))
    return a

主要代码:

for i in range(1,5):
        print(i)
        a='PH_lat_%d' % i 
        print (a)
        b='latOffset_%d' % i
        print (b)
        df2.a = df2.apply(lambda x: calculate_latoffset(x[b]), axis=1)

由于列名称仅相差(1,2,3,4)。所以我想调用函数calculate_latoffset并一次性计算所有列的所有行(PH_Lat_1,PH_Lat_2,PH_Lat_3,PH_Lat_4)。

使用上面的代码时,我收到此错误:

basic_conversion.py:46: UserWarning: Pandas doesn't allow columns to be created via a new attribute name - see https://pandas.pydata.org/pandas-docs/stable/indexing.html#attribute-access
  df2.a = df2.apply(lambda x: calculate_latoffset(x[b]), axis=1)

可能吗 ?请帮忙

python pandas dataframe indexing lambda
4个回答
7
投票

只需使用df2['a']而不是df2.a


2
投票

我能想到的解决方案是使用.loc获取列。你可以试试df.loc[:,a]而不是df.a。无法使用点方法创建Pandas数据帧列,以避免与数据帧属性发生潜在冲突。希望这可以帮助


1
投票

这是一个警告而非错误,因此您的代码仍然可以运行,但可能没有遵循您的意图。

  1. 简短回答:要为DataFrame创建新列,永远不要使用属性访问,正确的方法是使用[].loc索引: >>> df a b 0 7 6 1 5 8 >>> df['c'] = df.a + df.b >>> # OR >>> df.loc[:, 'c'] = df.a + df.b >>> df # c is an new added column a b c 0 7 6 13 1 5 8 13

更多的解释,Seires和DataFrame是pandas中的核心类和数据结构,当然它们也是Python类,因此在涉及pandas DataFrame和普通Python对象之间的属性访问时会有一些细微的区别。但它是well documented,可以很容易理解。只需注意几点:

  1. 在Python中,用户可以使用属性访问动态地将他们自己的数据属性添加到实例对象。 >>> class Dog(object): ... pass >>> dog = Dog() >>> vars(dog) {} >>> superdog = Dog() >>> vars(superdog) {} >>> dog.legs = 'I can run.' >>> superdog.wings = 'I can fly.' >>> vars(dog) {'legs': 'I can run.'} >>> vars(superdog) {'wings': 'I can fly.'}
  2. 在pandas中,索引和列与数据结构密切相关,您可以在DataFrame上的Series,column列上访问索引作为属性。 >>> import pandas as pd >>> import numpy as np >>> data = np.random.randint(low=0, high=10, size=(2,2)) >>> df = pd.DataFrame(data, columns=['a', 'b']) >>> df a b 0 7 6 1 5 8 >>> vars(df) {'_is_copy': None, '_data': BlockManager Items: Index(['a', 'b'], dtype='object') Axis 1: RangeIndex(start=0, stop=2, step=1) IntBlock: slice(0, 2, 1), 2 x 2, dtype: int64, '_item_cache': {}}
  3. 但是,pandas属性访问主要是方便读取和修改DataFrame的Series或列的现有元素。 qazxsw poi
  4. 并且,方便性是对完整功能的权衡。例如。您可以使用列名>>> df.a 0 7 1 5 Name: a, dtype: int64 >>> df.b = [1, 1] >>> df a b 0 7 1 1 5 1 创建DataFrame对象,但不能将它们作为属性访问,因为它们不是有效的Python标识符['space bar', '1', 'loc', 'min', 'index']1或与现有方法名称冲突。 space bar
  5. 在这些情况下,>>> data = np.random.randint(0, 10, size=(2, 5)) >>> df_special_col_names = pd.DataFrame(data, columns=['space bar', '1', 'loc', 'min', 'index']) >>> df_special_col_names space bar 1 loc min index 0 4 4 4 8 9 1 3 0 1 2 3 .loc.iloc索引是[],以完全访问/操作Series和DataFrame对象的索引和列。 the defined way
  6. 至于主题,要为DataFrame创建一个新列,正如您所看到的,>>> df_special_col_names['space bar'] 0 4 1 3 Name: space bar, dtype: int64 >>> df_special_col_names.loc[:, 'min'] 0 8 1 2 Name: min, dtype: int64 >>> df_special_col_names.iloc[:, 1] 0 4 1 0 Name: 1, dtype: int64 刚刚在核心数据结构旁边创建了一个新属性,因此从版本df.c = df.a + df.b及更高版本开始,此行为将引发0.21.0(不再沉默) )。 UserWarning
  7. 最后,回到简短的回答。

0
投票

>>> df a b 0 7 1 1 5 1 >>> df.c = df.a + df.b __main__:1: UserWarning: Pandas doesn't allow columns to be created via a new attribute name - see https://pandas.pydata.org/pandas-docs/stable/indexing.html#attribute-access >>> df['d'] = df.a + df.b >>> df a b d 0 7 1 8 1 5 1 6 >>> df.c 0 8 1 6 dtype: int64 >>> vars(df) {'_is_copy': None, '_data': BlockManager Items: Index(['a', 'b', 'd'], dtype='object') Axis 1: RangeIndex(start=0, stop=2, step=1) IntBlock: slice(0, 2, 1), 2 x 2, dtype: int64 IntBlock: slice(2, 3, 1), 1 x 2, dtype: int64, '_item_cache': {}, 'c': 0 8 1 6 dtype: int64} 中,您正在创建一个5列数据框,并且您尝试将值分配给单个字段。相反,df2.apply(lambda x: calculate_latoffset(x[b]), axis=1)应该提供所需的输出。

© www.soinside.com 2019 - 2024. All rights reserved.