在一列元组上使用 df.isin() 函数 | Pandas

Using df.isin() function over a column of tuples | Pandas

我有一个数据框,其中包含带有地理坐标和一些统计数据的维基百科文章。 'Availability' 列包含该文章可用的语言元组(未选择)。

我想做的是用 plotly 绘制气泡图,图例是这些语言的可用性。例如,在 ['ca','es'] 中,您将有 [],['ca'],['es'],['ca','es'] 表示不可用,仅在加泰罗尼亚语中,仅在西班牙语中或分别在两者中可用。

问题是,当尝试使用这些组合创建一个数据框时,使用 Dataframe.isin() 仅包含匹配的行,它总是 returns 一个空的 df。 数据框的列是: Columns: [French Title, Qitem, Pageviews, page_title_1, page_title_2, Availability, Lat, Lon, Text]

这是我的代码:

    fig = go.Figure()
    scale = 500
    for comb in combinations:

        df_sub = df[df['Availability'].isin(tuple(comb))] #The problem is here. This returns an empty DF
        
        if(len(df_sub.index)) == 0: continue #There are no occurrencies with that comb
        fig.add_trace(go.Scattergeo(
            lat=df_sub['Lat'],
            lon=df_sub['Lon'],
            text=df_sub['Text'],
            marker = dict(
                size = df[order_by],
                sizeref=2. * max(df[order_by]) / (scale ** 2),
                line_color='rgb(40,40,40)',
                line_width=0.5,
                sizemode='area'
            ), name = comb #Here is the underlying restriction. I need to separate the traces according to their availability.
        ))

PS:我想这与 pandas 不太适合使用列表或元组作为列值有关,但没有弄清楚如何实现我想要的.你们有什么想法吗?先感谢您。 Comb 显示为字符串或字符串元组:('es','ca') ,但是当我打印它们时 df['Availability] 中的值显示为 (es,ca)

示例数据框(抱歉我是 Stack overflow 的新手)**

    French Title      Qitem  Pageviews  \
0  Liban                       Q822       53903       
1  France                      Q142       25728       
2  Biélorussie                 Q184       21688       
3  ÃŽle Maurice                 Q2656389   20478       
4  Affaire Dupont de Ligonnès  Q16010109  16075       

                                        page_title_1  page_title_2  \
0  Líbano                                             Líban          
1  Francia                                            França         
2  Bielorrusia                                        Bielorússia    
3  Isla de Mauricio                                   Illa Maurici   
4  Asesinatos y desapariciones de Dupont de Ligonnès                 

  Availability              Lat              Lon  \
0  (es, ca)     33.90000000      35.53330000       
1  (es, ca)     48.86700000      2.32650000        
2  (es, ca)     53.528333333333  28.046666666667   
3  (es, ca)     -20.30084200     57.58209200       
4  (es,)        47.23613230      -1.56848610       

                                                                    Text  
0  Liban<br>(33.90000000, 35.53330000)<br>Q822                            
1  France<br>(48.86700000, 2.32650000)<br>Q142                            
2  Biélorussie<br>(53.528333333333, 28.046666666667)<br>Q184              
3  ÃŽle Maurice<br>(-20.30084200, 57.58209200)<br>Q2656389                 
4  Affaire Dupont de Ligonnès<br>(47.23613230, -1.56848610)<br>Q16010109  

您可以使用 Series.apply() 来实现您的目标:

df['Availability'].apply(lambda x: 'ca' in x)

如果 'ca' 在元组中,那将是 return True。它可以很容易地修改为 return 一些标签,例如。 Catalan.

最后我把元组变成了一个列表,因为由于不使用 df.isin() 它不会引发 Unhashable Type Error,并且能够通过使用 [=13 的组合来分离痕迹=](感谢 mkos 的想法):

 for comb in combinations:

    if len(comb) ==0:
        name ='Not available'
        df_sub = df[df['Availability'].apply(lambda x:  len(x)==0)]
    else:
        df_sub = df[df['Availability'].apply(lambda x: set(comb) == set(x))]
        name = ','.join(comb)
    if(len(df_sub.index)) == 0: continue
   

    fig.add_trace(go.Scattergeo(
        lat=df_sub['Lat'],
        lon=df_sub['Lon'],
        text=df_sub['Text'],
        marker = dict(
            size = df[order_by],
            sizeref=2. * max(df[order_by]) / (scale ** 2),
            line_color='rgb(40,40,40)',
            line_width=0.5,
            sizemode='area'
        ), name =name
    ))

你可以看到结果here