Как перебирать строки DataFrame и получать значения из dicts в столбцах? - PullRequest
0 голосов
/ 15 ноября 2018

Features_Frame

Каждый функциональный кадр будет пакетом данных.Я хотел бы извлечь все значения для ключевых «координат» в геометрии col и итеративно вставить в другой df.

При том же значении df я также хотел бы хранить данные, извлеченные из свойств col.Свойства col имеет много ключей.

Каждый исходный кадр будет иметь и «геометрию»: «координаты» и «свойства», которые будут состоять из различных ключей.

Каждый столбец в этом новом DataFrame будет ключом внутри либо »geometry 'или' properties '.

Например:

      coordinates          name
0      [-108.600,39.09]    'Target'
1      [51.459,82.04]      'Costco'
2      [-35.459,82.04]     'BJ's Wholesale Club'
3      [98.459,12.07]      'Walgreens'
4      [105.404,96.04]     'Walmart

Я могу получить доступ к обоим столбцам с помощью следующего:

coord_frame = features_frame['geometry'][:]
properties_frame = features_frame['properties'][:]

Но это только разбивает кадр надва.Обычно, если бы я сделал:

Feature_Frame['geometry'][:]['coordinates']

Я бы получил значения для ключа координат в столбце геометрии для всех строк, если бы я сделал:

Feature_Frame['properties'][:]['name']

Я бы получилзначение для ключа имени в свойствах col для всех строк.

Вместо этого я просто получаю сообщение об ошибке, в котором говорится, что имя или координаты не существуют.

Ответы [ 2 ]

0 голосов
/ 18 ноября 2018

Подача списка диктов pd.DataFrame конструктору

pd.Series.apply - это цикл уровня Python, за исключением того, что обычно ниже простого понимания списка. Гораздо лучшая идея - использовать оптимизированный код, используемый в конструкторе pd.DataFrame. Вот пример:

df = pd.DataFrame({'geometry': [{'coordinates': [-108.600,39.09], 'name': 'Target'},
                                {'coordinates': [51.459,82.04], 'name': 'Costco'}]})

print(df)

                                            geometry
0  {'coordinates': [-108.6, 39.09], 'name': 'Targ...
1  {'coordinates': [51.459, 82.04], 'name': 'Cost...

res = pd.DataFrame(df['geometry'].values.tolist())

print(res)

       coordinates    name
0  [-108.6, 39.09]  Target
1  [51.459, 82.04]  Costco

Используйте concat для нескольких серий словарей

Вышеприведенное можно распространить на произвольные серии словарей:

df = pd.DataFrame({'geometry': [{'coordinates': [-108.600,39.09], 'name': 'Target'},
                                {'coordinates': [51.459,82.04], 'name': 'Costco'}],
                   'properties': [{'osm_id': 288700723, 'osm_tye': 'W'},
                                  {'osm_id': 52734154, 'osm_tye': 'W'}]})

res = pd.concat((pd.DataFrame(df[col].values.tolist()) for col in df), axis=1)

print(res)

       coordinates    name     osm_id osm_tye
0  [-108.6, 39.09]  Target  288700723       W
1  [51.459, 82.04]  Costco   52734154       W
0 голосов
/ 15 ноября 2018

а как же

df_new = pd.DataFrame()

, а затем, например,

df_new['coordinates'] = features_frame['geometry'].apply(lambda x: x['coordinates'])

или

df_new['name'] = features_frame['properties'].apply(lambda x: x['name'])

И если вы хотите сделать это со всеми ключами, вы можете просто зациклить ключи примерного диктата в первом ряду:

for key in features_frame.geometry[0]:
    df_new[key] = features_frame.geometry.apply(lambda x: x[key])

for key in features_frame.properties[0]:
    df_new[key] = features_frame.properties.apply(lambda x: x[key])

дополнительный:
... и на всякий случай, если в geometry - и properties -дицитах есть идентичные ключи, их можно легко декорировать при создании новых столбцов, чтобы предотвратить перезапись:

for ...
    df_new['geom_' + key] = ...
for ...
    df_new['prop_' + key] = ...

EDIT:

В случае, если некоторые словари в столбце не имеют всех ключей, значение по умолчанию, например, None должен быть возвращен.
Чтобы добиться этого, просто используйте get -метод, который позволяет определять значение по умолчанию, в лямбда-функциях вместо индексации:

lambda x: x.get(key, None)

Это как минимум правильное решение для устранения ключевых ошибок.
Однако, если код не выполняет итерацию по всем ключам, поскольку dict в первой строке не является репрезентативным для всех dicts, сначала необходимо создать список всех ключей.
И есть разные возможности попасть в этот список:

  1. В идеале вы уже знаете все ключи из других источников. Затем вы можете поместить их в список и выполнить итерацию по нему вместо первого запроса.

  2. Возможно, вы знаете, что существует по крайней мере один диктовку с наибольшим количеством ключей и что этот самый длинный диктофон имеет все ключи, а ключи более коротких диктовок в одном столбце всегда являются подмножествами. Тогда вы можете найти

    longest_dict = sorted(df.geometry, key=len)[-1]
    
  3. Возможно, вы вообще ничего не знаете о ключах. Таким образом, вы должны собрать все различные ключи, которые появляются в любом месте столбца:

    all_keys = []
    for d in df.geometry:
        all_keys.extend(d)
    all_keys = set(all_keys)
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...