Как преобразовать функциональность в iterrows в одну строку в pandas

#python #pandas

#python #pandas

Вопрос:

Мои данные1 выглядят следующим образом:

 [
{"cut_id":1,"cut_label":"v024","cut_name":"State","value_label":"1","value":"andaman and nicobar islands"},
{"cut_id":3,"cut_label":"v024","cut_name":"State","value_label":"3","value":"arunachal pradesh"},
{"cut_id":635,"cut_label":"sdistri","cut_name":"District","value_label":"599","value":"pathanamthitta"},
{"cut_id":636,"cut_label":"sdistri","cut_name":"District","value_label":"600","value":"kollam"},
{"cut_id":637,"cut_label":"sdistri","cut_name":"District","value_label":"601","value":"thiruvananthapuram"}
]
  

Результат, который я хочу, выглядит следующим образом:

 [
{"value_label":"S1","value":"andaman and nicobar islands"},
{"value_label":"S3","value":"arunachal pradesh"},
{"value_label":"D599","value":"pathanamthitta"},
{"value_label":"D600","value":"kollam"},
{"value_label":"D601","value":"thiruvananthapuram"}
]
  

Я намереваюсь переименовать метку значения, добавив к числу символ ‘S’ или ‘D’ в зависимости от того, является ли это штатом или округом.

Это мой код:

 for _, r in data[
        (data['cut_name'] == 'State') | (data['cut_name'] == 'District')][
            ['cut_name', 'value', 'value_label']
    ].iterrows():
    cuts_data[r.cut_name[0] r.value_label] = r.value
  

Я получил ожидаемый результат, но есть ли способ сделать это в одной строке

Ответ №1:

Используйте str с индексацией для получения первого значения cut_name и при необходимости отфильтруйте его по Series.isin :

 mask = data['cut_name'].isin(['State','District'])
data.loc[mask, 'value_label'] = data['cut_name'].str[0]   data['value_label'].astype(str)
  

Если только State или District возможные значения:

 data['value_label'] = data['cut_name'].str[0]   data['value_label'].astype(str)
  

Для повышения производительности возможно использовать понимание списка (хорошая работа — отсутствие пропущенных значений):

 data['value_label'] = [c[0]   str(v) for c, v in zip(data['cut_name'], data['value_label'])]
  

Если нужен новый фрейм данных с отфильтрованными столбцами:

 new_df = data[['value','value_label']]
  

Комментарии:

1. Спасибо, как насчет lambda и apply??

2. @virupaksha — Я думаю, что это возможно с помощью data['value_label'] = data['cut_name'].apply(lambda x: x[0]) data['value_label'].astype(str) — какова причина для его использования?

3. @virupaksha — какая-то проблема?

Ответ №2:

Да, определенно есть:

 df.loc[df['cut_name'].isin(['State', 'District']), 'value_label'] = np.where(df['cut_name'] == 'State', 'S'   df['value_label'], 'D'   df['value_label'])
  

Ответ №3:

Вы можете сделать что-то подобное, если хотите использовать apply и lambda

 df = pd.DataFrame([
{"cut_id":1,"cut_label":"v024","cut_name":"State","value_label":"1","value":"andaman and nicobar islands"},
{"cut_id":3,"cut_label":"v024","cut_name":"State","value_label":"3","value":"arunachal pradesh"},
{"cut_id":635,"cut_label":"sdistri","cut_name":"District","value_label":"599","value":"pathanamthitta"},
{"cut_id":636,"cut_label":"sdistri","cut_name":"District","value_label":"600","value":"kollam"},
{"cut_id":637,"cut_label":"sdistri","cut_name":"District","value_label":"601","value":"thiruvananthapuram"}
])

n_df = pd.DataFrame()

n_df['value'] = df['value']
n_df['value_label'] = df.apply(lambda x : x['cut_name'][0]   x['value_label'], axis=1)

n_df.T.to_dict().values()

#Output

[{'value': 'andaman and nicobar islands', 'value_label': 'S1'}, {'value': 'arunachal pradesh', 'value_label': 'S3'}, {'value': 'pathanamthitta', 'value_label': 'D599'}, {'value': 'kollam', 'value_label': 'D600'}, {'value': 'thiruvananthapuram', 'value_label': 'D601'}]