如何基于dataframe列中的列表值创建多个标志列?

ltqd579y  于 2021-06-25  发布在  Hive
关注(0)|答案(3)|浏览(336)

表如下所示:

ID  |CITY
    ----------------------------------
    1  |London|Paris|Tokyo
    2  |Tokyo|Barcelona|Mumbai|London
    3  |Vienna|Paris|Seattle

“城市”列包含约1000+个以|分隔的值
我想创建一个flag列来指示一个人是否只访问了感兴趣的城市。

city_of_interest=['Paris','Seattle','Tokyo']

列表中有20个这样的值。
输出应如下所示:

ID      |Paris   | Seattle | Tokyo    
     -------------------------------------------
     1       |1       |0        |1      
     2       |0       |0        |1       
     3       |1       |1        |0

解决方案可以是pandas或pyspark。

xdnvmnnf

xdnvmnnf1#

Pandas解决方案
要使用的第一个转换列表 DataFrame.explode :

new_df=df.copy()
new_df['CITY']=new_df['CITY'].str.lstrip('|').str.split('|')

# print(new_df)

# ID                                CITY

# 0   1              [London, Paris, Tokyo]

# 1   2  [Tokyo, Barcelona, Mumbai, London]

# 2   3            [Vienna, Paris, Seattle]

然后我们可以使用:
方法1: DataFrame.pivot_table ```
new_df=( new_df.explode('CITY')
.pivot_table(columns='CITY',index='ID',aggfunc='size',fill_value=0)
[city_of_interest]
.reset_index()
.rename_axis(columns=None)
)
print(new_df)

方法2: `DataFrame.groupby` +  `DataFrame.unstack` ```
new_df=( new_df.explode('CITY')
               .groupby(['ID'])
               .CITY
               .value_counts()
               .unstack('CITY',fill_value=0)[city_of_interest]
               .reset_index()
               .rename_axis(columns=None)

                )
print(new_df)

输出新数据框:

ID  Paris  Seattle  Tokyo
0   1      1        0      1
1   2      0        0      1
2   3      1        1      0
tmb3ates

tmb3ates2#

使用自定义项检查“感兴趣的城市”值是否位于分隔列中。

from pyspark.sql.functions import udf

# Input list

city_of_interest=['Paris','Seattle','Tokyo']

# UDF definition

def city_present(city_name,city_list):
    return len(set([city_name]) & set(city_list.split('|')))

city_present_udf = udf(city_present,IntegerType())

# Converting cities list to a column of array type for adding columns to the dataframe

city_array = array(*[lit(city) for city in city_of_interest])
l = len(city_of_interest)
col_names = df.columns + [city for city in city_of_interest]
result = df.select(df.columns + [city_present_udf(city_array[i],df.city) for i in range(l)])
result = result.toDF(*col_names)
result.show()
nwnhqdif

nwnhqdif3#

对于pyspark,使用split+array\u contains:

from pyspark.sql.functions import split, array_contains

df.withColumn('cities', split('CITY', '\|')) \
  .select('ID', *[ array_contains('cities', c).astype('int').alias(c) for c in city_of_interest ]) 
  .show()
+---+-----+-------+-----+
| ID|Paris|Seattle|Tokyo|
+---+-----+-------+-----+
|  1|    1|      0|    1|
|  2|    0|      0|    1|
|  3|    1|      1|    0|
+---+-----+-------+-----+

对于Pandas,请使用series.str.get\u dummies:

df[city_of_interest] = df.CITY.str.get_dummies()[city_of_interest]
df = df.drop('CITY', axis=1)

相关问题