Files
IIabm/AmendFirm_20230216.ipynb
T
2023-02-20 16:02:39 +08:00

830 KiB

In [37]:
import pandas as pd
import numpy as np
import math
import statsmodels.formula.api as smf
from sklearn.preprocessing import MinMaxScaler
import networkx as nx
import matplotlib.pyplot as plt
import seaborn as sns

plt.rcParams['font.sans-serif'] = 'SimHei'

# init graph bom
BomNodes = pd.read_csv('BomNodes.csv', index_col=0)
BomNodes.set_index('Code', inplace=True)
BomCateNet = pd.read_csv('BomCateNet.csv', index_col=0)
BomCateNet.fillna(0, inplace=True)

G = nx.from_pandas_adjacency(BomCateNet, create_using=nx.MultiDiGraph())

labels_dict = {}
for code in G.nodes:
    labels_dict[code] = BomNodes.loc[code].to_dict()
nx.set_node_attributes(G, labels_dict)

# load firm
Firm = pd.read_csv("Firm.csv")
Firm_copy = Firm.copy()

# get log revenue
Firm_copy['Revenue_Log'] = Firm_copy['Revenue'].map(math.log)
Firm_copy['Num_Employ_Log'] = Firm_copy['Num_Employ'].map(math.log)
data_ols = Firm_copy[Firm_copy[['Revenue_Log', 'Num_Employ_Log']].notnull().all(axis=1)][['Revenue_Log', 'Num_Employ_Log']]

ols_model = smf.ols('Revenue_Log ~ Num_Employ_Log', data=data_ols)
ols_results = ols_model.fit()
b = ols_results.params.Intercept
a = ols_results.params.Num_Employ_Log
# sns.regplot(x='Num_Employ_Log',y='Revenue_Log',data=data_ols[data_ols.notnull().all(axis=1)])

Firm_copy.loc[Firm_copy['Revenue_Log'].isnull(), 'Revenue_Log'] = Firm_copy[Firm_copy['Revenue_Log'].isnull()]['Num_Employ_Log'].map(lambda x: a*x + b)
series_Revenue_Log = Firm_copy.pop('Revenue_Log')
Firm_copy.insert(Firm_copy.columns.get_loc('Revenue'),'Revenue_Log', series_Revenue_Log)
series_Num_Employ_Log = Firm_copy.pop('Num_Employ_Log')
Firm_copy.insert(Firm_copy.columns.get_loc('Num_Employ'),'Num_Employ_Log', series_Num_Employ_Log)

# git nodes based on tiers
dict_nodes = {0: sorted([node for node in G.nodes() if G.out_degree(node)==0])}
level = 1
while True:
    nodes = [list(G.predecessors(node)) for node in dict_nodes[level-1]]
    nodes = sorted(list(set([i for j in nodes for i in j])))
    if nodes:
        dict_nodes[level] = nodes
        level += 1
    else:
        break

# lift firm from neighboring tier
for tier in list(dict_nodes.keys())[1:]:
    for node in dict_nodes[tier]:
        list_neighbors = list(G.neighbors(node))
        firm_list = Firm_copy.index[(Firm_copy[list_neighbors]==1).all(axis=1)].to_list()
        if firm_list: # there exist firm that produces all components
            # lift firm with size above average in firm_list
            average_size = Firm_copy.loc[firm_list, 'Revenue_Log'].mean()
            firm_above_mean = Firm_copy.loc[firm_list].loc[Firm_copy.loc[firm_list, 'Revenue_Log'] > average_size].index.to_list()
            Firm_copy.loc[firm_above_mean, node] = 1
            Firm_copy.loc[firm_above_mean, list_neighbors] = np.nan
        else: # select top 10% firm in terms of size
            pass

# output
Firm_copy.to_csv('Firm_amended.csv', index=False, encoding='utf-8-sig')
C:\Users\25759\AppData\Local\Temp\ipykernel_3908\2756876345.py:42: PerformanceWarning: DataFrame is highly fragmented.  This is usually the result of calling `frame.insert` many times, which has poor performance.  Consider joining all columns at once using pd.concat(axis=1) instead. To get a de-fragmented frame, use `newframe = frame.copy()`
  Firm_copy.insert(Firm_copy.columns.get_loc('Revenue'),'Revenue_Log', series_Revenue_Log)
C:\Users\25759\AppData\Local\Temp\ipykernel_3908\2756876345.py:44: PerformanceWarning: DataFrame is highly fragmented.  This is usually the result of calling `frame.insert` many times, which has poor performance.  Consider joining all columns at once using pd.concat(axis=1) instead. To get a de-fragmented frame, use `newframe = frame.copy()`
  Firm_copy.insert(Firm_copy.columns.get_loc('Num_Employ'),'Num_Employ_Log', series_Num_Employ_Log)
In [38]:
# visualization
firm_num_dict = {}
for node in nx.nodes(G):
    firm_num_dict[node]= sum(Firm_copy[node]==1)
nx.set_node_attributes(G, firm_num_dict, name="Num_Firm")

pos = nx.nx_agraph.graphviz_layout(G, prog="twopi", args="")
dict_num_firm = nx.get_node_attributes(G, 'Num_Firm')
dict_node_name = nx.get_node_attributes(G, 'Name')
node_labels = {}
for node in nx.nodes(G):
    # node_labels[node] = f"{node} {str(dict_node_name[node])} {str(dict_num_firm[node])}"
    node_labels[node] = f"{str(dict_num_firm[node])}"
plt.figure(figsize=(12, 12), dpi=300)
nx.draw_networkx_nodes(G, pos)
nx.draw_networkx_edges(G, pos)
nx.draw_networkx_labels(G, pos, labels = node_labels, font_size=4)
plt.show()
In [39]:
import seaborn as sns
data = Firm_copy[Firm_copy['Num_Employ'] > 0]['Num_Employ']
print(data)
sns.displot(data)
Out [39]:
0       7393.0
1        171.0
2        113.0
3         24.0
4        242.0
        ...   
165       60.0
166      292.0
167    13371.0
168     5057.0
169     5173.0
Name: Num_Employ, Length: 129, dtype: float64
<seaborn.axisgrid.FacetGrid at 0x1dd8eb0dfa0>
In [40]:
import seaborn as sns
data = Firm_copy[Firm_copy['Revenue'] > 0]['Revenue']
print(data)
sns.displot(data)
Out [40]:
0      1.089000e+10
1      1.380000e+08
6      1.590000e+08
11     6.750000e+08
13     2.470000e+09
           ...     
160    6.894667e+09
162    5.880760e+07
167    4.110000e+10
168    4.519000e+09
169    3.470400e+10
Name: Revenue, Length: 110, dtype: float64
<seaborn.axisgrid.FacetGrid at 0x1dd8f42e2e0>
In [ ]: