Transpose nested list in python
Use zip
with *
and map
:
>>> map(list, zip(*a))
[['AAA', 'BBB', 'CCC', 'DDD', 'EEE', 'FFF', 'GGG', 'HHH', 'III'],
['1', '262', '86', '48', '8', '39', '170', '16', '4'],
['1', '56', '84', '362', '33', '82', '296', '40', '3'],
['10', '238', '149', '205', '96', '89', '223', '65', '5'],
['92', '142', '30', '237', '336', '140', '210', '50', '2']]
Note that map
returns a map object in Python 3, so there you would need list(map(list, zip(*a)))
Using a list comprehension
with zip(*...)
, this would work as is in both Python 2 and 3.
[list(x) for x in zip(*a)]
NumPy way:
>>> import numpy as np
>>> np.array(a).T.tolist()
[['AAA', 'BBB', 'CCC', 'DDD', 'EEE', 'FFF', 'GGG', 'HHH', 'III'],
['1', '262', '86', '48', '8', '39', '170', '16', '4'],
['1', '56', '84', '362', '33', '82', '296', '40', '3'],
['10', '238', '149', '205', '96', '89', '223', '65', '5'],
['92', '142', '30', '237', '336', '140', '210', '50', '2']]
Transpose list of lists
Python 3:
# short circuits at shortest nested list if table is jagged:
list(map(list, zip(*l)))
# discards no data if jagged and fills short nested lists with None
list(map(list, itertools.zip_longest(*l, fillvalue=None)))
Python 2:
map(list, zip(*l))
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
Explanation:
There are two things we need to know to understand what's going on:
- The signature of zip:
zip(*iterables)
This meanszip
expects an arbitrary number of arguments each of which must be iterable. E.g.zip([1, 2], [3, 4], [5, 6])
. - Unpacked argument lists: Given a sequence of arguments
args
,f(*args)
will callf
such that each element inargs
is a separate positional argument off
. itertools.zip_longest
does not discard any data if the number of elements of the nested lists are not the same (homogenous), and instead fills in the shorter nested lists then zips them up.
Coming back to the input from the question l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
, zip(*l)
would be equivalent to zip([1, 2, 3], [4, 5, 6], [7, 8, 9])
. The rest is just making sure the result is a list of lists instead of a list of tuples.
How would I succinctly transpose nested lists?
use mylist = zip(*mylist)
:
>>> original = [[1, 2, 3, 4], [1, 2, 3, 4], [2, 3, 4, 5]]
>>> transposed = zip(*original)
>>> transposed
[(1, 1, 2), (2, 2, 3), (3, 3, 4), (4, 4, 5)]
>>> original[2][3]
5
>>> transposed[3][2]
5
How it works: zip(*original)
is equal to zip(original[0], original[1], original[2])
. which in turn is equal to: zip([1, 2, 3, 4], [1, 2, 3, 4], [2, 3, 4, 5]).
How to transpose a nested list in python
This is known as transposing, and you can do it like this:
lst = [('a1','b1','c1'),('a2','b2','c2'),('a3','b3','c3'),('a4','b4','c4')]
transposed_lst = list(zip(*lst))
transposed_lst
evaluates to:
[('a1', 'a2', 'a3', 'a4'), ('b1', 'b2', 'b3', 'b4'), ('c1', 'c2', 'c3', 'c4')]
transpose nested list
For the specific example, you can use this pretty simple approach:
split(unlist(l), c("x", "y"))
#$x
#[1] 1 2 3
#
#$y
#[1] 4 5 6
It recycles the x-y vector and splits on that.
To generalize this to "n" elements in each list, you can use:
l = list(list(1, 4, 5), list(2, 5, 5), list(3, 6, 5)) # larger test case
split(unlist(l, use.names = FALSE), paste0("x", seq_len(length(l[[1L]]))))
# $x1
# [1] 1 2 3
#
# $x2
# [1] 4 5 6
#
# $x3
# [1] 5 5 5
This assumes, that all the list elements on the top-level of l
have the same length, as in your example.
Transpose a dataframe to a nested list of list
pandas.Series.tolist() can convert series value to list.
print(input_df['continents'].unique().tolist())
print(input_df.groupby('continents', sort=False)['countries'].apply(lambda x: x.unique().tolist()).tolist())
print(input_df.groupby(['continents', 'countries'], sort=False)['cities'].apply(lambda x: [x.unique().tolist()]).tolist())
['Asia', 'America']
[['China'], ['United States', 'Canada']]
[[['Beijing', 'Shenzhen']], [['New York']], [['Toronto']]]
As for a general approach, the first approach occurred to me is to loop through the columns of df
.
def list_wrapper(alist, times):
for _ in range(times):
alist = [alist]
return alist
columns_name = input_df.columns.values.tolist()
for i in range(len(columns_name)):
if i == 0:
print(input_df[columns_name[i]].unique().tolist())
else:
print(input_df.groupby(columns_name[0:i], sort=False)[columns_name[i]].apply(lambda x: list_wrapper(x.unique().tolist(), i-1)).tolist())
Transpose (rotate?) nested list
If I understand you correctly, you want to first transpose all the sublists then transpose the newly transposed groups:
print([list(zip(*sub)) for sub in zip(*l)])
Output:
In [69]: [list(zip(*sub)) for sub in zip(*l)]
Out[69]: [[('a', 'e'), ('b', 'f')], [('c', 'g'), ('d', 'h')]]
If you want some map foo with a lambda:
In [70]: list(map(list, map(lambda x: zip(*x), zip(*l))))
Out[70]: [[('a', 'e'), ('b', 'f')], [('c', 'g'), ('d', 'h'
For python2 you don't need the extra map call but I would use itertools.izip
to do the initial transpose.:
In [9]: from itertools import izip
In [10]: map(lambda x: zip(*x), izip(*l))
Out[10]: [[('a', 'e'), ('b', 'f')], [('c', 'g'), ('d', 'h')]]
Return values from nested lists into PandasDataFrame
A simple way to do this is by converting the list into a dictionary and then creating a Data Frame from that dictionary as explained below:
l =[[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]
# Creating a dictionary using dictionary comprehension
d = {'col'+str(i) : l[i] for i in range(len(l))}
df = pd.DataFrame(d)
Related Topics
Splitting a Pandas Dataframe Column by Delimiter
Index of Duplicates Items in a Python List
Is There a Matplotlib Equivalent of Matlab's Datacursormode
Check If a File Is Not Open Nor Being Used by Another Process
Why Doesn't a Python Dict.Update() Return the Object
Why Does Sys.Exit() Not Exit When Called Inside a Thread in Python
How Include Static Files to Setuptools - Python Package
Which Is the Easiest Way to Simulate Keyboard and Mouse on Python
Sorting a List of Dot-Separated Numbers, Like Software Versions
How to Avoid Explicit 'Self' in Python
How to Source Virtualenv Activate in a Bash Script
Remove Trailing Newline from the Elements of a String List
Setting Different Bar Color in Matplotlib Python