熊猫将功能应用于多个列并创建多个列来存储结果



我有以下df

country    street           postcode    id
SA                         XX0         1
GB       17 abc road                   2
BE       129 def street    127         3
US       nan               nan         4

我想计算countrystreetpostcode值的熵;空字符串或 NaN 默认将获得0.25的值;

from entropy import shannon_entropy
vendor_fields_to_measure_entropy_on = ('country', 'vendor_name', 'town', 'postcode', 'street')
fields_to_update = tuple([key + '_entropy_val' for key in vendor_fields_to_measure_entropy_on])
for fields in zip(vendor_fields_to_measure_entropy_on, fields_to_update):
entropy_score = []
for item in df[fields[0]].values:
item_as_str = str(item)
if len(item_as_str) > 0 and item_as_str != 'NaN':
entropy_score.append(shannon_entropy(item_as_str))
else:
entropy_score.append(.25)
df[fields[1]] = entropy_score

我想知道这样做的最佳方法是什么,所以结果看起来像,

country    street           postcode    id    
SA                         XX0         1                        
GB       17 abc road                   2
BE       129 def street    127         3
US       nan               nan         4   

country_entropy_val  street_entropy_val  postcode_entropy_val
0.125               0.25                0.11478697512328288
0.125               0.38697440929431765 0.25
0.125               0.39775073104910885 0.19812031562256
0.125               0.25                0.25
>>> fields = ['country', 'street', 'postcode']
>>> for col in fields:
...     df[f'{col}_entropy'] = df[col].apply(lambda x: shannon_entropy(str(x)) if not pd.isna(x) else 0.25)
... 
from io import StringIO
import pandas as pd
# sample data
df = pd.read_fwf(StringIO("""country    street           postcode    id
SA                         XX0         1
GB       17 abc road                   2
BE       129 def street    127         3
US       nan               nan         4
"""))
# Did not install the package so providing  this as a substitute function
def shannon_entropy(x): # fake function
return(.1)
# organize into a function  to simplify the  apply
def calc(item):
# ensure that blank is stripped of spaces
item_as_str = str(item).strip()
# how you read the data affects the NaN - use lower here to work both ways
if len(item_as_str) > 0 and item_as_str.lower() != 'nan':
return shannon_entropy(item_as_str)
else:
return .25
# make these selectors lists, not tuples
vendor_fields_to_measure_entropy_on = ['country', 'postcode', 'street']
fields_to_update = [key + '_entropy_val' for key in vendor_fields_to_measure_entropy_on]
# applymap will apply to each cell
df2  = df[vendor_fields_to_measure_entropy_on].applymap(calc)
# fix the columns
df2.columns = fields_to_update

结果:

country_entropy_val  postcode_entropy_val  street_entropy_val
0                  0.1                  0.10                0.25
1                  0.1                  0.25                0.10
2                  0.1                  0.10                0.10
3                  0.1                  0.25                0.25

最新更新