Python pandas apply()会导致UnboundLocalError

Python pandas apply()会导致UnboundLocalError,python,pandas,dataframe,apply,Python,Pandas,Dataframe,Apply,我有一个数据帧(df_集群),有两列[客户Id,集群]。大约有13个集群,我正在尝试使用python中的apply()为每个集群指定一个名称。我在过去使用过相同的函数,它工作得很好,但现在我得到了“UnboundLocalError”错误 如果我做错了什么,请告诉我。我对apply()的理解是,它跨轴传递函数(在本例中,将为每一行传递函数cluster_name) 这是密码 def cluster_name(df): if df['cluster'] == 1: valu

我有一个数据帧(df_集群),有两列[客户Id,集群]。大约有13个集群,我正在尝试使用python中的apply()为每个集群指定一个名称。我在过去使用过相同的函数,它工作得很好,但现在我得到了“UnboundLocalError”错误

如果我做错了什么,请告诉我。我对apply()的理解是,它跨轴传递函数(在本例中,将为每一行传递函数cluster_name)

这是密码

def cluster_name(df):
    if df['cluster'] == 1:
        value = 'A'
    elif df['cluster'] == 2:
        value = 'B'    
    elif df['cluster'] == 3:
        value = 'C'
    elif df['cluster'] == 4:
        value = 'D'
    elif df['cluster'] == 5:
        value = 'E'
    elif df['cluster'] == 6:
        value = 'F'
    elif df['cluster'] == 7:
        value = 'G'
    return value

df_cluster['cluster_name'] = df_cluster.apply(cluster_name, axis = 1)
错误

UnboundLocalError回溯(最近一次调用)
在里面
16返回值
17
--->18 df_cluster['cluster_name']=df_cluster.apply(cluster_name,axis=1)
19 df_cluster['cluster_name'].值_计数()
/opt/cloudera/parcels/Anaconda/envs/py36/lib/python3.6/site-packages/pandas/core/frame.py在应用中(self、func、axis、broadcast、raw、reduce、result_type、args、**kwds)
6926科威特第纳尔=科威特第纳尔,
6927         )
->6928返回操作获取结果()
6929
6930 def应用映射(自身,功能):
/获取结果(self)中的opt/cloudera/parcels/Anaconda/envs/py36/lib/python3.6/site-packages/pandas/core/apply.py
184返回self.apply_raw()
185
-->186返回自我。应用_标准()
187
188 def应用\空\结果(自身):
/opt/cloudera/parcels/Anaconda/envs/py36/lib/python3.6/site-packages/pandas/core/apply.py in apply_标准(self)
290
291#使用级数生成器计算结果
-->292自应用_系列_发生器()
293
294#总结结果
/opt/cloudera/parcels/Anaconda/envs/py36/lib/python3.6/site-packages/pandas/core/apply.py in-apply_-series_生成器(self)
319试试:
320用于枚举中的i、v(系列):
-->321结果[i]=自f(v)
322个键。追加(v.name)
323例外情况除外,如e:
集群名称(df)中的
14 elif df[“集群”]==7:
15值='G'
--->16返回值
17
18 df_cluster['cluster_name']=df_cluster.apply(cluster_name,axis=1)
UnboundLocalError:(“赋值前引用了局部变量'value','在索引0处发生')
'''

您的问题似乎已经在评论中得到了回答,因此我将提出一种更加面向熊猫的方法来解决您的问题。对数据帧使用
apply(axis=1)
速度非常慢,而且几乎没有必要(与迭代数据帧中的行相同),因此更好的方法是使用矢量化方法。最简单的方法是在字典中定义集群->集群\名称映射,并使用
map
方法:

df = pd.DataFrame(
    {"cluster": [1,2,3,4,5,6,7]}
)

# repeat this dataframe 10000 times
df = pd.concat([df] * 10000)
应用方法:

def mapping_func(row):
    if row['cluster'] == 1:
        value = 'A'
    elif row['cluster'] == 2:
        value = 'B'    
    elif row['cluster'] == 3:
        value = 'C'
    elif row['cluster'] == 4:
        value = 'D'
    elif row['cluster'] == 5:
        value = 'E'
    elif row['cluster'] == 6:
        value = 'F'
    elif row['cluster'] == 7:
        value = 'G'
    else:
        # This is a "catch-all" in case none of the values in the column are 1-7
        value = "Z"
        
    return value

%timeit df.apply(mapping_func, axis=1)
# 1.32 s ± 91.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
.map
方法

mapping_dict = {
    1: "A",
    2: "B",
    3: "C",
    4: "D",
    5: "E",
    6: "F",
    7: "G"
}

# the `fillna` is our "catch-all" statement.
#  essentially if `map` encounters a value not in the dictionary
#  it will place a NaN there. So I fill those NaNs with "Z" to
#  be consistent with the above example
%timeit df["cluster"].map(mapping_dict).fillna("Z")
# 4.87 ms ± 195 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

我们可以看到,使用字典方法的
映射
应用
快得多,同时还避免了一长串
if/elif
语句。

函数中缺少
else

def cluster_name(df):
    if df['cluster'] == 1:
        value = 'A'
    elif df['cluster'] == 2:
        value = 'B'    
    elif df['cluster'] == 3:
        value = 'C'
    elif df['cluster'] == 4:
        value = 'D'
    elif df['cluster'] == 5:
        value = 'E'
    elif df['cluster'] == 6:
        value = 'F'
    elif df['cluster'] == 7:
        value = 'G'
    else:
        value = ...
    return value
否则,如果
df['cluster']
不在值{1,2,…,7}中,则不会设置
,这将产生异常。

  • 手动创建
    if-else
    功能被高估,可能会错过一个条件
  • 由于您将字母指定为
    'cluster\u name'
    ,因此使用可获取所有字母的
    列表,并将它们指定给
    'cluster'
    • 从压缩后的值创建一个
      dict
      ,并创建
      'cluster\u name'
  • 此实现使用列中的唯一值来创建映射,因此在赋值之前引用的局部变量“value”不会出现问题。
    • 在出现错误的情况下,这是因为
      返回值
      在列中有一个值不在
      if else
      条件中时执行,这意味着函数中未分配
将熊猫作为pd导入
导入字符串
#测试数据帧
df=pd.DataFrame({'cluster':范围(1,11)})
#群集列中的唯一值
clusters=sorted(df.cluster.unique())
#创建要映射的dict
cluster\u map=dict(zip(clusters,string.ascii\u大写))
#创建群集名称列
df['cluster\u name']=df.cluster.map(cluster\u map)
#df
群集名称
01 A
1.2 B
2 3 C
三维
4.5 E
5.6楼
6.7克
7.8小时
8.9我
9 10 J

似乎列中的一个值不在函数中。如果
df['cluster']>7
,预期的行为是什么?然后,
永远不会被赋值,但您仍会尝试返回它。尝试在开始时为
value
分配一些内容,或者在返回之前在末尾使用catch-all
else:
def cluster_name(df):
    if df['cluster'] == 1:
        value = 'A'
    elif df['cluster'] == 2:
        value = 'B'    
    elif df['cluster'] == 3:
        value = 'C'
    elif df['cluster'] == 4:
        value = 'D'
    elif df['cluster'] == 5:
        value = 'E'
    elif df['cluster'] == 6:
        value = 'F'
    elif df['cluster'] == 7:
        value = 'G'
    else:
        value = ...
    return value