{"cells":[{"metadata":{},"cell_type":"markdown","source":"After reading this [discussion](https://www.kaggle.com/c/champs-scalar-coupling/discussion/96586#latest-557994), I have decided to explore the [**graph**](https://en.wikipedia.org/wiki/Graph_(discrete_mathematics) (in its mathematical definition) of each molecule and see what I can get from it. For that, I will be using the [networkx](https://networkx.github.io/documentation/stable/) library. \n\nLet's go!"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# Some imports\nimport pandas as pd\nimport numpy as np\nimport networkx as nx\nimport matplotlib.pylab as plt","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Load the data and add L2 distance computation between atoms"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = pd.read_csv(\"../input/train.csv\")\ntest_df = pd.read_csv(\"../input/test.csv\")\nstructures_df = pd.read_csv('../input/structures.csv')\ntest_df['scalar_coupling_constant'] = np.nan\ndf = pd.concat([train_df, test_df])\ndel train_df\ndel test_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\nfor atom_index in [0, 1]:\n    renamed_columns = {col: col + \"_\" + str(atom_index) for col in [\"x\", \"y\", \"z\", \"atom_index\", \n                                                                    \"atom\"]}\n    df = (df.merge(structures_df.rename(columns=renamed_columns),\n                   on=['molecule_name', 'atom_index_' + str(atom_index)], how='inner'))\ndf['distance_l2'] = ((df['x_0'] - df['x_1']) ** 2 + (df['y_0'] - df['y_1'])\n                     ** 2 + (df['z_0'] - df['z_1']) ** 2) ** 0.5","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"MOLECULE_NAMES = df['molecule_name'].unique()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Construct the graph and plot it"},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_molecule_graph(df, molecule_name):\n    molecule_df = df.loc[lambda df: df['molecule_name'] == molecule_name]\n    labels = molecule_df[['atom_1', 'atom_index_1']].set_index('atom_index_1')['atom_1'].to_dict()\n    labels.update(molecule_df[['atom_0', 'atom_index_0']].set_index('atom_index_0')['atom_0'].to_dict())\n    graph = nx.from_pandas_edgelist(molecule_df, source='atom_index_0', \n                                    target='atom_index_1', edge_attr='scalar_coupling_constant', \n                                    create_using=nx.Graph())\n    return graph, labels\n\ndef draw_graph(graph, labels, weight=\"distance_l2\"):\n    position = nx.spring_layout(graph, weight=weight)\n    fig, ax = plt.subplots(1, 1, figsize=(6, 6))\n    nx.draw_networkx_nodes(graph, position, node_color='red', alpha = 0.8, ax=ax)\n    nx.draw_networkx_edges(graph, position, edge_color='blue', alpha = 0.6, ax=ax)\n    nx.draw_networkx_labels(graph, position, labels, font_size=16, ax=ax)\n    return ax","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Plotting for only few molecules\nfor molecule_name in MOLECULE_NAMES[:10]:\n    graph, labels = get_molecule_graph(df, molecule_name)\n    ax = draw_graph(graph, labels)\n    ax.set_title(f\"Graph for {molecule_name}\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"That's it for now, I will update this kernel whenever I find new interesting things. :)"}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}