Python 将函数应用于多列并创建多列以存储结果

Python 将函数应用于多列并创建多列以存储结果,python,python-3.x,pandas,entropy,Python,Python 3.x,Pandas,Entropy,我有以下df country street postcode id SA XX0 1 GB 17 abc road 2 BE 129 def street 127 3 US nan nan 4 我想计算国家、街道和邮政编码的值的熵;空字符串或NaN

我有以下
df

country    street           postcode    id
  SA                         XX0         1
  GB       17 abc road                   2
  BE       129 def street    127         3
  US       nan               nan         4
我想计算
国家
街道
邮政编码
的值的熵;空字符串或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
结果:

   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
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