{"action":"created","issue":{"url":"https://api.github.com/repos/networkx/networkx/issues/1340","labels_url":"https://api.github.com/repos/networkx/networkx/issues/1340/labels{/name}","comments_url":"https://api.github.com/repos/networkx/networkx/issues/1340/comments","events_url":"https://api.github.com/repos/networkx/networkx/issues/1340/events","html_url":"https://github.com/networkx/networkx/pull/1340","id":55078449,"number":1340,"title":"Modify from_pandas_dataframe to accept non-square inputs ","user":{"login":"rnelsonchem","id":3750670,"avatar_url":"https://avatars.githubusercontent.com/u/3750670?v=3","gravatar_id":"","url":"https://api.github.com/users/rnelsonchem","html_url":"https://github.com/rnelsonchem","followers_url":"https://api.github.com/users/rnelsonchem/followers","following_url":"https://api.github.com/users/rnelsonchem/following{/other_user}","gists_url":"https://api.github.com/users/rnelsonchem/gists{/gist_id}","starred_url":"https://api.github.com/users/rnelsonchem/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rnelsonchem/subscriptions","organizations_url":"https://api.github.com/users/rnelsonchem/orgs","repos_url":"https://api.github.com/users/rnelsonchem/repos","events_url":"https://api.github.com/users/rnelsonchem/events{/privacy}","received_events_url":"https://api.github.com/users/rnelsonchem/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2015-01-21T21:18:18Z","updated_at":"2015-01-22T03:14:07Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/networkx/networkx/pulls/1340","html_url":"https://github.com/networkx/networkx/pull/1340","diff_url":"https://github.com/networkx/networkx/pull/1340.diff","patch_url":"https://github.com/networkx/networkx/pull/1340.patch"},"body":"First PR, so let me say that NetworkX has been very useful in the past. Thanks!\r\n\r\nI was looking at the dev docs and was happy to see that there is some work being done to handle Pandas DataFrames as inputs for graph creation (from_pandas_dataframe). Unfortunately (for me), the source looks to be a very thin wrapper around from_numpy_matrix. This doesn't work for the DataFrames I create, which are sparse and not square (Example below). This PR modifies from_pandas_dataframe in a way that accepts non-square DFs. What I've done is to create a generator function that takes a DataFrame and returns an [ebunch](http://networkx.github.io/documentation/development/reference/glossary.html#term-ebunch). The generator is passed to the `add_edges_from` constructor. This works fine for all shapes of DataFrame, including the square case that is already covered.\r\n\r\nTested Python 3.4 on Linux.\r\n\r\nThere's still a couple of problems... First of all, I wrote a test that follows the from_numpy_matrix tests. Unfortunately, I wasn't working on my machine because it couldn't find `np` and `pd`. Pointers?  Second, should this have flags to ignore zero and nan? Or should they just be ignored without asking? \r\n\r\nExample:\r\nI might have a connectivity DataFrame that looks like the following (just made this up):\r\n\r\ndonor|A|B|C|\r\n---|---|---|---\r\naccept|||\r\n|D|2.7|0.4|0.3|\r\n|E|0.00|0.03|0|\r\n|F|0.00|0.7|2.1|\r\n|G|0.52|0|1.2|\r\n\r\nIn this extreme example, there is not any overlap between the two sets and they are different lengths. I could [rebuild my DataFrame](http://stackoverflow.com/questions/21207872/construct-networkx-graph-from-pandas-dataframe) to have the same columns and indices ; however, this is a bit of extra work and creates a very large table of empty values. \r\n\r\nIf the above Dataframe is stored in `df`, then the modified function will produce:\r\n\r\n    G=nx.from_pandas_dataframe(df)\r\n    print(G.edges(data=True))\r\n\r\n[('A', 'G', {'weight': 0.52000000000000002}),\r\n ('A', 'D', {'weight': 2.7000000000000002}),\r\n ('G', 'C', {'weight': 1.2}),\r\n ('E', 'B', {'weight': 0.029999999999999999}),\r\n ('B', 'F', {'weight': 0.69999999999999996}),\r\n ('B', 'D', {'weight': 0.40000000000000002}),\r\n ('F', 'C', {'weight': 2.1000000000000001}),\r\n ('D', 'C', {'weight': 0.29999999999999999})]\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/networkx/networkx/issues/comments/70965271","html_url":"https://github.com/networkx/networkx/pull/1340#issuecomment-70965271","issue_url":"https://api.github.com/repos/networkx/networkx/issues/1340","id":70965271,"user":{"login":"rnelsonchem","id":3750670,"avatar_url":"https://avatars.githubusercontent.com/u/3750670?v=3","gravatar_id":"","url":"https://api.github.com/users/rnelsonchem","html_url":"https://github.com/rnelsonchem","followers_url":"https://api.github.com/users/rnelsonchem/followers","following_url":"https://api.github.com/users/rnelsonchem/following{/other_user}","gists_url":"https://api.github.com/users/rnelsonchem/gists{/gist_id}","starred_url":"https://api.github.com/users/rnelsonchem/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rnelsonchem/subscriptions","organizations_url":"https://api.github.com/users/rnelsonchem/orgs","repos_url":"https://api.github.com/users/rnelsonchem/repos","events_url":"https://api.github.com/users/rnelsonchem/events{/privacy}","received_events_url":"https://api.github.com/users/rnelsonchem/received_events","type":"User","site_admin":false},"created_at":"2015-01-22T03:14:07Z","updated_at":"2015-01-22T03:14:07Z","body":"Actually, I can speed this up and simplify the code if you would allow a completely different format of the DataFrame input. For example, if you have the DataFrame as such:\r\n\r\nIndex | NodeA | NodeB |weight\r\n---|---|---|---\r\n0 | A | G | 0.52\r\n1 | E | B | 0.03\r\netc... \r\n\r\nThen you can write a generator function that only needs to do a single loop through the rows of the table. (The one I've written does two nested loops.) In addition, you could pretty easily write this to accept extra columns for additional information about the edges. In this case, though, you would want to have a bunch of extra flags for the selecting node columns, weight column, etc.\r\n\r\nI think this is going to be a more common format for people working with DataFrames in general. This is the way I extract my data. In order to get my previous attempt to work, I had to do a [pivot table](http://pandas.pydata.org/pandas-docs/stable/reshaping.html#reshaping-by-pivoting-dataframe-objects) from my original DataFrame, which generated a lot of unnecessary data.\r\n\r\nI played around with this and got something working. Depending on what people are thinking about this change in general. I could modify my original pull request or make a new one if you'd like to see what I'm talking about."}}