830 KiB
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 [ ]: