Как применить функцию в Pandas к ячейке в каждой строке, где другая ячейка в той же строке соответствует условию? - PullRequest
0 голосов
/ 08 июня 2019

Я пытаюсь использовать метод строки панд "str.zfill", чтобы добавить начальные нули к ячейке в том же столбце для каждой строки в кадре данных, где другая ячейка в этой строке удовлетворяет определенному условию.Поэтому для любой данной строки в моем DataFrame «excodes», когда значение в столбце «LOB_SVC_CD» равно «MTG», примените метод str.zfill(5) к ячейке в столбце «PS_CD».Если значение в «LOB_SVC_CD» не равно «MTG», оставьте значение в «PS_CD» как есть.

Я пробовал несколько пользовательских функций, "np.where" и несколько лямбд / apply / map.Я получаю ошибки по всем из них.

#Custom Function
def add_zero(column):
    if excodes.loc[excodes.LOB_SVC_CD == 'MTG']:
        excodes.PS_CD.str.zfill(5)
    else:
        return excodes.PS_CD

excodes['code'] = excodes.apply(add_zero)

#Custom Function with For Loop
def add_zero2(column):
    code = []
    for row(i) in column:
        if excodes.LOB_SVC_CD == 'MTG':
        code.append(excodes.PS_CD.str.zfill(5))
    else:
        code.append(excodes.PS_CD)
excodes['Code'] = code

excodes['code'] = excodes.apply(add_zero)

#np.Where
mask = excodes[excodes.LOB_SVC_CD == 'MTG']
excodes['code'] = pd.DataFrame[np.where(mask, excodes.PS_CD.str.zfill(5), excodes.PS_CD)]

#Lambda
excodes['code'] = excodes['LOB_SVC_CD'].map(lambda x: excodes.PS_CD.str.zfill(5)) if x[excodes.LOB_SVC_CD == 'MTG'] else excodes.PS_CD)  

#Assign with a "Where"
excodes.assign((excodes.PS_CD.str.zfill(5)).where(excodes.LOB_SVC_CD == 'MTG')) 

Ожидаемые результаты будут либо:

  • создать новый с именем "code" со всеми значениями в "PS_CD"задаются начальные нули в строках, где excodes.LOB_SVC_CD == 'MTG'

  • добавление начальных нулей к значениям в excodes["PS_CD"], когда строка excodes['LOB_SVC_CD'] == 'MTG'

Сообщения об ошибках, которые я получаю, - на каждом из подходов, которые я пробовал:

#Custom Function: 
"ValueError: ('The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().', 'occurred at index PS_CD')"

# Custom Function with For Loop:
"SyntaxError: can't assign to function call"

#np.Where:
"ValueError: operands could not be broadcast together with shapes (152,7) (720,) (720,)"

#Apply Lambda:
"string indices must be integers"

#Assign with a "Where":
"TypeError: assign() takes 1 positional argument but 2 were given"

Ответы [ 2 ]

0 голосов
/ 10 июня 2019

Мое взятие:

>>> import pandas
>>> df = pandas.DataFrame(data = [['123', 'MTG'],['321', 'CLOC']], columns = ['PS_CD', 'LOB_SVC_CD'])
>>> df
  PS_CD LOB_SVC_CD
0   123        MTG
1   321       CLOC
>>>
>>> df['PS_CD'] = df.apply(lambda row: row['PS_CD'].zfill(5) if row['LOB_SVC_CD'] == 'MTG' else row['PS_CD'], axis='columns')
>>> df
   PS_CD LOB_SVC_CD
0  00123        MTG
1    321       CLOC

Использование лямбды вернет значение для каждой строки, zfilled PS_CD, если LOB_SVC_CD был MTG, иначе оригинальный PS_CD.

0 голосов
/ 08 июня 2019

Кажется, это работает:)

# Ensure the data in the PS_CD are strings
data["PS_CD"] = data["PS_CD"].astype(str)

# Iterate over all rows
for index in data.index:
  # If the LOB_SVC_CD is "MTG"
  if (data.loc[index, "LOB_SVC_CD"] == "MTG"):
    # Apply the zfill(5) in the PS_CD on the same row (index)
    data.loc[index, "PS_CD"] = data.loc[index, "PS_CD"].zfill(5)

# Print the result
print(data)

Альтернативный способ (возможно, немного больше Python-ish):)

# Ensure the data in the PS_CD are strings
data["PS_CD"] = data["PS_CD"].astype(str)

# Custom function for applying the zfill
def my_zfill(x, y):
  return y.zfill(5) if x == "MTG" else y

# Iterate over the data applying the custom function on each row
data["PS_CD"] = pd.Series([my_zfill(x, y) for x, y in zip(data["LOB_SVC_CD"], data["PS_CD"])])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...