I got data using API with below code and trying to select the ones that are necessary and make it into a dataframe.
import requests
import pandas as pd
trait_type_responses= []
for t_id in range(1,10):
url=f"https://api.opensea.io/api/v1/asset/0xed5af388653567af2f388e6224dc7c4b3241c544/{t_id}/?account_address=0xed5af388653567af2f388e6224dc7c4b3241c544&include_orders=false"
headers = {"X-API-KEY": "api_key"}
response = requests.get(url, headers=headers)
azuki_json = response.json()['traits']
trait_type_responses.append(azuki_json)
trait_type_responses
so the trait_type_responses is as below;
[[{'trait_type': 'Type',
'value': 'Human',
'display_type': None,
'max_value': None,
'trait_count': 9018,
'order': None},
{'trait_type': 'Background',
'value': 'Off White D',
'display_type': None,
'max_value': None,
'trait_count': 1990,
'order': None},
{'trait_type': 'Mouth',
'value': 'Lipstick',
'display_type': None,
'max_value': None,
'trait_count': 408,
'order': None},
{'trait_type': 'Eyes',
'value': 'Daydreaming',
'display_type': None,
'max_value': None,
'trait_count': 387,
'order': None},
{'trait_type': 'Hair',
'value': 'Pink Hairband',
'display_type': None,
'max_value': None,
'trait_count': 77,
'order': None},
{'trait_type': 'Clothing',
'value': 'White Qipao with Fur',
'display_type': None,
'max_value': None,
'trait_count': 84,
'order': None},
{'trait_type': 'Offhand',
'value': 'Gloves',
'display_type': None,
'max_value': None,
'trait_count': 111,
'order': None}],
[{'trait_type': 'Type',
'value': 'Human',
'display_type': None,
'max_value': None,
'trait_count': 9018,
'order': None},
{'trait_type': 'Background',
'value': 'Red',
'display_type': None,
'max_value': None,
'trait_count': 1006,
'order': None},
{'trait_type': 'Eyes',
'value': 'Ruby',
'display_type': None,
'max_value': None,
'trait_count': 381,
'order': None},
{'trait_type': 'Mouth',
'value': 'Chewing',
'display_type': None,
'max_value': None,
'trait_count': 351,
'order': None},
{'trait_type': 'Hair',
'value': 'Pink Flowy',
'display_type': None,
'max_value': None,
'trait_count': 87,
'order': None},
{'trait_type': 'Ear',
'value': 'Red Tassel',
'display_type': None,
'max_value': None,
'trait_count': 33,
'order': None},
{'trait_type': 'Clothing',
'value': 'Vest',
'display_type': None,
'max_value': None,
'trait_count': 160,
'order': None}],
[{'trait_type': 'Type',
'value': 'Human',
'display_type': None,
'max_value': None,
'trait_count': 9018,
'order': None},
{'trait_type': 'Background',
'value': 'Red',
'display_type': None,
'max_value': None,
'trait_count': 1006,
'order': None},
{'trait_type': 'Mouth',
'value': 'Grass',
'display_type': None,
'max_value': None,
'trait_count': 390,
'order': None},
{'trait_type': 'Hair',
'value': 'Green Spiky',
'display_type': None,
'max_value': None,
'trait_count': 117,
'order': None},
{'trait_type': 'Offhand',
'value': 'Katana',
'display_type': None,
'max_value': None,
'trait_count': 439,
'order': None},
{'trait_type': 'Eyes',
'value': 'Careless',
'display_type': None,
'max_value': None,
'trait_count': 381,
'order': None},
{'trait_type': 'Clothing',
'value': 'Green Yukata',
'display_type': None,
'max_value': None,
'trait_count': 208,
'order': None},
{'trait_type': 'Neck',
'value': 'Frog Headphones',
'display_type': None,
'max_value': None,
'trait_count': 52,
'order': None},
{'trait_type': 'Headgear',
'value': 'Frog Headband',
'display_type': None,
'max_value': None,
'trait_count': 94,
'order': None}],
[{'trait_type': 'Type',
'value': 'Human',
'display_type': None,
'max_value': None,
'trait_count': 9018,
'order': None},
{'trait_type': 'Background',
'value': 'Off White D',
'display_type': None,
'max_value': None,
'trait_count': 1990,
'order': None},
{'trait_type': 'Mouth',
'value': 'Smirk',
'display_type': None,
'max_value': None,
'trait_count': 726,
'order': None},
{'trait_type': 'Hair',
'value': 'Brown Dreadlocks',
'display_type': None,
'max_value': None,
'trait_count': 21,
'order': None},
{'trait_type': 'Offhand',
'value': 'Katana',
'display_type': None,
'max_value': None,
'trait_count': 439,
'order': None},
{'trait_type': 'Clothing',
'value': 'White Qipao with Fur',
'display_type': None,
'max_value': None,
'trait_count': 84,
'order': None},
{'trait_type': 'Eyes',
'value': 'Lightning',
'display_type': None,
'max_value': None,
'trait_count': 46,
'order': None}],
[{'trait_type': 'Type',
'value': 'Human',
'display_type': None,
'max_value': None,
'trait_count': 9018,
'order': None},
{'trait_type': 'Background',
'value': 'Red',
'display_type': None,
'max_value': None,
'trait_count': 1006,
'order': None},
{'trait_type': 'Offhand',
'value': 'Leather Katana',
'display_type': None,
'max_value': None,
'trait_count': 414,
'order': None},
{'trait_type': 'Eyes',
'value': 'Suspicious',
'display_type': None,
'max_value': None,
'trait_count': 312,
'order': None},
{'trait_type': 'Mouth',
'value': 'Chuckle',
'display_type': None,
'max_value': None,
'trait_count': 411,
'order': None},
{'trait_type': 'Face',
'value': 'Red Stripes Face Paint',
'display_type': None,
'max_value': None,
'trait_count': 290,
'order': None},
{'trait_type': 'Hair',
'value': 'Blonde Swept Back',
'display_type': None,
'max_value': None,
'trait_count': 98,
'order': None},
{'trait_type': 'Clothing',
'value': 'Red Perfecto Jacket',
'display_type': None,
'max_value': None,
'trait_count': 83,
'order': None}],
[{'trait_type': 'Type',
'value': 'Human',
'display_type': None,
'max_value': None,
'trait_count': 9018,
'order': None},
{'trait_type': 'Background',
'value': 'Off White A',
'display_type': None,
'max_value': None,
'trait_count': 1814,
'order': None},
{'trait_type': 'Offhand',
'value': 'Leather Katana',
'display_type': None,
'max_value': None,
'trait_count': 414,
'order': None},
{'trait_type': 'Eyes',
'value': 'Calm',
'display_type': None,
'max_value': None,
'trait_count': 376,
'order': None},
{'trait_type': 'Mouth',
'value': 'Tongue Out',
'display_type': None,
'max_value': None,
'trait_count': 202,
'order': None},
{'trait_type': 'Clothing',
'value': 'Alpine Jacket',
'display_type': None,
'max_value': None,
'trait_count': 115,
'order': None},
{'trait_type': 'Hair',
'value': 'Teal Bun',
'display_type': None,
'max_value': None,
'trait_count': 109,
'order': None}],
[{'trait_type': 'Type',
'value': 'Human',
'display_type': None,
'max_value': None,
'trait_count': 9018,
'order': None},
{'trait_type': 'Background',
'value': 'Off White A',
'display_type': None,
'max_value': None,
'trait_count': 1814,
'order': None},
{'trait_type': 'Offhand',
'value': 'Leather Katana',
'display_type': None,
'max_value': None,
'trait_count': 414,
'order': None},
{'trait_type': 'Clothing',
'value': 'Light Kimono',
'display_type': None,
'max_value': None,
'trait_count': 311,
'order': None},
{'trait_type': 'Mouth',
'value': 'Bubble Gum',
'display_type': None,
'max_value': None,
'trait_count': 281,
'order': None},
{'trait_type': 'Headgear',
'value': 'Full Bandana',
'display_type': None,
'max_value': None,
'trait_count': 182,
'order': None},
{'trait_type': 'Eyes',
'value': 'Suspicious',
'display_type': None,
'max_value': None,
'trait_count': 312,
'order': None},
{'trait_type': 'Hair',
'value': 'Orange Samurai',
'display_type': None,
'max_value': None,
'trait_count': 98,
'order': None}],
[{'trait_type': 'Type',
'value': 'Human',
'display_type': None,
'max_value': None,
'trait_count': 9018,
'order': None},
{'trait_type': 'Background',
'value': 'Off White B',
'display_type': None,
'max_value': None,
'trait_count': 1758,
'order': None},
{'trait_type': 'Mouth',
'value': 'Grass',
'display_type': None,
'max_value': None,
'trait_count': 390,
'order': None},
{'trait_type': 'Face',
'value': 'Blush',
'display_type': None,
'max_value': None,
'trait_count': 108,
'order': None},
{'trait_type': 'Eyes',
'value': 'Relaxed',
'display_type': None,
'max_value': None,
'trait_count': 339,
'order': None},
{'trait_type': 'Hair',
'value': 'Silver Pixie',
'display_type': None,
'max_value': None,
'trait_count': 82,
'order': None},
{'trait_type': 'Clothing',
'value': 'Hoodie',
'display_type': None,
'max_value': None,
'trait_count': 148,
'order': None},
{'trait_type': 'Neck',
'value': 'Choker',
'display_type': None,
'max_value': None,
'trait_count': 148,
'order': None}],
[{'trait_type': 'Clothing',
'value': 'White Yukata',
'display_type': None,
'max_value': None,
'trait_count': 167,
'order': None},
{'trait_type': 'Background',
'value': 'Off White D',
'display_type': None,
'max_value': None,
'trait_count': 1990,
'order': None},
{'trait_type': 'Offhand',
'value': 'Bat',
'display_type': None,
'max_value': None,
'trait_count': 392,
'order': None},
{'trait_type': 'Eyes',
'value': 'Chill',
'display_type': None,
'max_value': None,
'trait_count': 392,
'order': None},
{'trait_type': 'Mouth',
'value': 'Chuckle',
'display_type': None,
'max_value': None,
'trait_count': 411,
'order': None},
{'trait_type': 'Type',
'value': 'Blue',
'display_type': None,
'max_value': None,
'trait_count': 444,
'order': None},
{'trait_type': 'Hair',
'value': 'Silver Spiky',
'display_type': None,
'max_value': None,
'trait_count': 73,
'order': None}]]
from the above, I'm trying to use the value of 'trait_type' and 'value' and make a dataframe with a column index containing value of 'trait_type' and the column should be filled with the matching value of 'value' of corresponding 'trait_type'.
So to cut things short, below is the dataframe I wish to make, the column indices are values of the 'trait_type', which are;
Counter(trait_type_responses).keys()
dict_keys(['Type', 'Background', 'Mouth', 'Eyes', 'Hair', 'Clothing', 'Offhand', 'Ear', 'Neck', 'Headgear', 'Face', 'Special'])
Type | Background | Mouth | Eyes | Hair | Clothing | Offhand | Ear | Neck | Headgear | Face | Special | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | Human | Off White D | Lipstick | Daydreaming | Pink Hairband | White Qipao with Fur | Gloves | None | None | None | None | None |
1 | and so on | |||||||||||
2 | . | |||||||||||
3 | . | |||||||||||
4 | . | |||||||||||
5 | ||||||||||||
6 | ||||||||||||
7 | ||||||||||||
8 | ||||||||||||
9 | ||||||||||||
10 | ||||||||||||
11 | ||||||||||||
. | ||||||||||||
. | ||||||||||||
. |
I tried json_normalize but failed to make the dataframe that I want.
I also tried selecting and appending the information that I want to use by indexing the rows and appending it but it turns out the order of the data is mixed up so indexing the number of rows doesn't seem to work.
for i in range(len(trait_type_responses)):
Type.append(trait_type_responses[i][0]['value'])
Background.append(trait_type_responses[i][1]['value'])
Mouth.append(trait_type_responses[i][2]['value'])
Eyes.append(trait_type_responses[i][3]['value'])
Hair.append(trait_type_responses[i][4]['value'])
Clothing.append(trait_type_responses[i][5]['value'])
Offhand.append(trait_type_responses[i][6]['value'])
df= pd.DataFrame({"Type":Type,
"Background":Background,
"Mouth":Mouth,
"Eyes":Eyes,
"Hair":Hair,
"Clothing":Clothing,
"Offhand":Offhand})
df
and result, which some of the value seems to be a mixed up.
I presume it can be done by selecting rows containing specific values but have no idea how to do and make the dataframe I want.
Any help would be greatly appreciated.
FYI, the reason why the row index of the dataframe that I wish to make doesn't match with the number of loops I've set is because I've cut down the number of loops to small number for the simplicity.
CodePudding user response:
You could rebuild your list of dictionaries using trait_type
as a key and value
as a value for every dict in your response.
pd.DataFrame([{x['trait_type']:x['value'] for x in d} for d in trait_type_responses])