1 Востаннє редагувалося frz (11.07.2021 23:35:48)

Тема: Складний вибір в pandas

Ламаю голову. Є json:

{
  "odata.metadata":"https://example1.com/odata/$metadata#Contacts","value":[
    {
      "Addresses":[
        {
          "ContactId":"35aa05d1-21c7-493d-96e3-00003c966732","AssociatedEntity":"ac7a9ec8-b71b-486b-8b3b-41b6bc11f936",...
        }
      ],"ContactId":"35aa05d1-21c7-493d-96e3-00003c966732",...
    },{
      "Addresses":[
        {
          "ContactId":"ca717463-734d-4f2f-a01e-00006ff0c806","AssociatedEntity":"bda08493-7ae0-47cf-8d3a-f1a486498836",...
        }
      ],"ContactId":"ca717463-734d-4f2f-a01e-00006ff0c806",...
    },

Мені потрібно за допомогою pandas вибрати Addresses.ContactId і Addresses.AssociatedEntity, однак поки що вдається вибрати лише Addresses в цілому:

df1a = df[['Addresses']].copy()
print(df1a)

Addresses
0    [{'ContactId': '35aa05d1-21c7-493d-96e3-00003c...
1    [{'ContactId': 'ca717463-734d-4f2f-a01e-00006f...
2    [{'ContactId': '2cfb4580-2aa6-4e7a-9042-000075...
3    [{'ContactId': 'c6fc4e49-34a7-4eb0-8b5d-00008d...
4    [{'ContactId': 'cbfef02a-c1df-4753-aef7-0000a5...
..                                                 ...
995  [{'ContactId': 'c1565f0c-e7ed-4e7a-b53d-018532...
996  [{'ContactId': '74b26660-0d19-465d-bfd4-01871e...
997  [{'ContactId': 'c5c2ff45-c36f-4316-9272-01878d...
998  [{'ContactId': 'aa32a531-daef-415d-a7c7-0187ac...
999  [{'ContactId': '9fbd7888-7dd8-4f0c-a851-01895b...

[1000 rows x 1 columns]

Як тут добратися до Addresses.ContactId?

----

Upd: без pandas це доволі тривіально:

j = response_json['value']
i = 0
print('ContactId' + " " + 'AssociatedEntity')
for x in j:
    i = i + 1
    if i<4:
        for y in x['Addresses']:
            print(y['ContactId'] + " " + y['AssociatedEntity'])

ContactId AssociatedEntity
35aa05d1-21c7-493d-96e3-00003c966732 ac7a9ec8-b71b-486b-8b3b-41b6bc11f936
ca717463-734d-4f2f-a01e-00006ff0c806 bda08493-7ae0-47cf-8d3a-f1a486498836
2cfb4580-2aa6-4e7a-9042-000075733364 a1e7f700-cead-4be6-bc95-a49e7aca3638

Однак цимес pandas якраз в тому, що не потрібно ітерацій, тобто все відбувається швидко, незалежно скільки тисяч рядків буде в джейсоні... Тож сподіваюся знайти рішення для pandas.

2

Re: Складний вибір в pandas

Від модератора: будь ласка, не засмічуйте інші гілки. У вас конкретне питання, а форум для того й придуманий, щоб ставити питання у відповідних розділах.

Подякували: leofun011

3

Re: Складний вибір в pandas

Для початку: "непотрібно ітерацій" не буває. Бувають ліниві виклики, коли реальна обробка відкладається до того моменту, коли реально знадобиться, наприклад, буде зроблено запит до конкретної комірки або спробують змінити початкову інформацію.

Що ж до вашого питання, то, наскільки я розумію, це

df['Addresses', ('ContactId','AssociatedEntity')]

Якби ви навели фрагмент, який можна виконувати, то я б перед відповіддю зміг перевірити це.

Подякували: leofun011

4

Re: Складний вибір в pandas

Якби ви навели фрагмент, який можна виконувати

ось
import json
import pandas as pd

txt1 = '{"odata.metadata":"https://example1.com/odata/$metadata#Contacts","value":[    {      "Addresses":[        {          "ContactId":"35aa05d1-21c7-493d-96e3-00003c966732","AssociatedEntity":"ac7a9ec8-b71b-486b-8b3b-41b6bc11f936"        }      ],"ContactId2":"35aa05d1-21c7-493d-96e3-00003c966732"    },{      "Addresses":[        {          "ContactId":"ca717463-734d-4f2f-a01e-00006ff0c806","AssociatedEntity":"bda08493-7ae0-47cf-8d3a-f1a486498836"        }      ],"ContactId2":"ca717463-734d-4f2f-a01e-00006ff0c806"    }]}'

json2 = json.loads(txt1)

print("json:\n")

print(json2)

df = pd.json_normalize(json2['value'])

print("\npandas df (1):\n")

df1a = df['Addresses'].copy()
print(df1a)

print("\npandas df (2):\n")

df1b = df['Addresses', ('ContactId','AssociatedEntity')].copy()
print(df1b)

json:

{'odata.metadata': 'https://example1.com/odata/$metadata#Contacts', 'value': [{'Addresses': [{'ContactId': '35aa05d1-21c7-493d-96e3-00003c966732', 'AssociatedEntity': 'ac7a9ec8-b71b-486b-8b3b-41b6bc11f936'}], 'ContactId2': '35aa05d1-21c7-493d-96e3-00003c966732'}, {'Addresses': [{'ContactId': 'ca717463-734d-4f2f-a01e-00006ff0c806', 'AssociatedEntity': 'bda08493-7ae0-47cf-8d3a-f1a486498836'}], 'ContactId2': 'ca717463-734d-4f2f-a01e-00006ff0c806'}]}

pandas df (1):

0    [{'ContactId': '35aa05d1-21c7-493d-96e3-00003c...
1    [{'ContactId': 'ca717463-734d-4f2f-a01e-00006f...
Name: Addresses, dtype: object

pandas df (2):

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
~/anaconda3/lib/python3.8/site-packages/pandas/core/indexes/base.py in get_loc(self, key, method, tolerance)
   2645             try:
-> 2646                 return self._engine.get_loc(key)
   2647             except KeyError:

pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()

pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()

pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()

pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()

KeyError: ('Addresses', ('ContactId', 'AssociatedEntity'))

During handling of the above exception, another exception occurred:

KeyError                                  Traceback (most recent call last)
<ipython-input-2-d68ec0703d62> in <module>
     19 print("\npandas df (2):\n")
     20
---> 21 df1b = df['Addresses', ('ContactId','AssociatedEntity')].copy()
     22 print(df1b)

~/anaconda3/lib/python3.8/site-packages/pandas/core/frame.py in __getitem__(self, key)
   2798             if self.columns.nlevels > 1:
   2799                 return self._getitem_multilevel(key)
-> 2800             indexer = self.columns.get_loc(key)
   2801             if is_integer(indexer):
   2802                 indexer = [indexer]

~/anaconda3/lib/python3.8/site-packages/pandas/core/indexes/base.py in get_loc(self, key, method, tolerance)
   2646                 return self._engine.get_loc(key)
   2647             except KeyError:
-> 2648                 return self._engine.get_loc(self._maybe_cast_indexer(key))
   2649         indexer = self.get_indexer([key], method=method, tolerance=tolerance)
   2650         if indexer.ndim > 1 or indexer.size > 1:

pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()

pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()

pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()

pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()

KeyError: ('Addresses', ('ContactId', 'AssociatedEntity'))

5 Востаннє редагувалося frz (12.07.2021 15:50:06)

Re: Складний вибір в pandas

ось так спрацювало:

df3 = pd.json_normalize(json2["value"], "Addresses")
print(df3)

ContactId                      AssociatedEntity
0  35aa05d1-21c7-493d-96e3-00003c966732  ac7a9ec8-b71b-486b-8b3b-41b6bc11f936
1  ca717463-734d-4f2f-a01e-00006ff0c806  bda08493-7ae0-47cf-8d3a-f1a486498836