sn1 / meta2frame.py
steffenc's picture
Fix dataframe construction bug and improve logging/tqdm outputs
08fa697
raw
history blame
2.56 kB
import glob
import tqdm
import pickle
import os
import datetime
import torch
import bittensor as bt
import pandas as pd
import plotly.express as px
ROOT_DIR = './data/metagraph/'
def load_metagraphs(root_dir, netuid, block_min=0, block_max=3_000_000):
metagraphs = []
match_path = os.path.join(root_dir, str(netuid), '*.pkl')
files = glob.glob(match_path)
print(f'Found {len(files)} metagraphs in {match_path}')
valid_files = [path for path in files if block_min <= int(path.split('/')[-1].split('.')[0]) <= block_max]
pbar = tqdm.tqdm(valid_files, desc=f'Loading {len(valid_files)} metagraph snapshots')
for path in pbar:
with open(path, 'rb') as f:
metagraph = pickle.load(f)
metagraphs.append(metagraph)
return sorted(metagraphs, key=lambda x: x.block)
def get_block_timestamp(block, subtensor):
info = subtensor.substrate.get_block(block_number=int(block))
extrinsic_call = info['extrinsics'][0]['call']
return extrinsic_call.value_serialized['call_args'][0]['value']
def block_to_time(blocks, subtensor=None):
if not isinstance(blocks, pd.Series):
blocks = pd.Series(blocks)
if subtensor is None:
subtensor = bt.subtensor(network='archive')
timestamps = {}
unique_blocks = set(blocks)
for block in tqdm.tqdm(unique_blocks, desc=f'Mapping {len(unique_blocks)} blocks to timestamps'):
timestamps[block] = get_block_timestamp(block, subtensor)
return blocks.map(timestamps).apply(pd.to_datetime, unit='ms')
def make_dataframe(netuid, root_dir=ROOT_DIR, cols=None, block_min=0, block_max=3_000_000, weights=False):
if cols is None:
cols = ['stake','emission','trust','validator_trust','dividends','incentive','R', 'consensus','validator_permit']
frames = []
metagraphs = load_metagraphs(root_dir, netuid, block_min, block_max)
for m in metagraphs:
frame = pd.DataFrame({k: getattr(m, k) for k in cols})
frame['block'] = m.block.item()
frame['netuid'] = netuid
frame['uid'] = range(len(frame))
frame['hotkey'] = [axon.hotkey for axon in m.axons]
frame['coldkey'] = [axon.coldkey for axon in m.axons]
if weights and m.W is not None:
# convert NxN tensor to a list of lists so it fits into the dataframe
frame['weights'] = [w.tolist() for w in m.W]
frames.append(frame)
df = pd.concat(frames)
df['timestamp'] = block_to_time(df['block'])
return df.sort_values(by=['timestamp','block','uid'])