How to unzip an Array?
Use transpose
:
> zipped = x.zip(y)
=> [[1, 4], [2, 5], [3, 6]]
> x2, y2 = zipped.transpose
> x2
=> [1, 2, 3]
> y2
=> [4, 5, 6]
Unzip a NumPy array
You can only ever unpack the first dimension of an array, but the dimension you want to unpack is the second one. This means in your case, you can do:
x10, x11 = br.T
Be aware that x10
and x11
will be a view into br
! This means if you change any of the values in any of these arrays, you will change the other variables too.
If your array has more than 2D dimensions (extra [
and ]
), check the shape of your array using
br.shape
and if you see superfluous empty dimensions (1
), remove them using
br = br.squeeze()
Type of zip and unzip array functions?
I got a solution for unzip
that does what you want.
function unzip<
T extends [...{ [K in keyof S]: S[K] }][], S extends any[]
>(arr: [...T]): T[0] extends infer A
? { [K in keyof A]: T[number][K & keyof T[number]][] }
: never
{
const maxLength = Math.max(...arr.map((x) => x.length));
return arr.reduce(
(acc: any, val) => {
val.forEach((v, i) => acc[i].push(v));
return acc;
},
range(maxLength).map(() => [])
);
}
Let's see if it works:
const a = unzip([[1, "a"], [2, "b"], [3, "c"]])
// ^? [number[], string[]]
const b = unzip([[1, "a", new Date()], [2, "b", new Date()], [3, "c", new Date()]] )
// ^? [number[], string[], Date[]]
const c = unzip([[1, "a"], [2, "b"], [3, undefined]])
// ^? [number[], (string | undefined)[]]
Playground
Here is an alternative solution that is fully compatible with the solution above. But for array literals, this will produce more accurate return types.
type ValidContent =
| null
| string
| number
| boolean
| Array<JSON>
| Date
| undefined
| {
[prop: string]: ValidContent
}
type UnzipReturn<T extends any[]> = T[0] extends infer A
? {
[K in keyof A]: [...{
[K2 in keyof T]: T[K2][K & keyof T[K2]]
}]
}
: never
function unzip<
T extends [...{[K in keyof S]: S[K]}][], S extends ValidContent[]
>(arr: [...T]): UnzipReturn<T> {
const maxLength = Math.max(...arr.map((x) => x.length));
return arr.reduce(
(acc: any, val) => {
val.forEach((v, i) => acc[i].push(v));
return acc;
},
range(maxLength).map(() => [])
);
}
const a = unzip([[1, "a"], [2, "b"], [3, "c"]])
// ^? [[1, 2, 3], ["a", "b", "c"]]
const b = unzip([[1, "a", new Date()], [2, "b", new Date()], [3, "c", new Date()]] )
// ^? [[1, 2, 3], ["a", "b", "c"], [Date, Date, Date]]
const c = unzip([[1, "a"], [2, "b"], [3, undefined]])
// ^? [[1, 2, 3], ["a", "b", undefined]]
const d = unzip([[1, "a"], [2, "b"], [3, "c"]] as [number, string][])
// ^? [number[], string[]]
Playground
Transpose/Unzip Function (inverse of zip)?
zip
is its own inverse! Provided you use the special * operator.
>>> zip(*[('a', 1), ('b', 2), ('c', 3), ('d', 4)])
[('a', 'b', 'c', 'd'), (1, 2, 3, 4)]
The way this works is by calling zip
with the arguments:
zip(('a', 1), ('b', 2), ('c', 3), ('d', 4))
… except the arguments are passed to zip
directly (after being converted to a tuple), so there's no need to worry about the number of arguments getting too big.
unzip list of tuples into numpy arrays
Your list of tuples can be converted into a 2-d numpy array by calling np.array
. This can then be transposed and then unpacked along the first dimension using tuple assignment:
b, c = np.array(a).T
Here this gives:
>>> import numpy as np
>>> a = [(1,2), (3,4)]
>>> b, c = np.array(a).T # or: np.array(a).transpose()
>>> b
array([1, 3])
>>> c
array([2, 4])
Caveat: you will have a temporary array with the same number of elements as a
, so it might be less memory-efficient than your original solution, particularly if you are unpacking into a larger number of 1d arrays.
Unzip an array of tuples in julia
For larger arrays use @ivirshup's solution below.
For smaller arrays, you can use zip
and splitting.
You can achieve the same thing in Julia by using the zip()
function (docs here). zip()
expects many tuples to work with so you have to use the splatting operator ...
to supply your arguments. Also in Julia you have to use the collect()
function to then transform your iterables into an array (if you want to).
Here are these functions in action:
arr = [(1,2), (3,4), (5,6)]
# wtihout splatting
collect(zip((1,2), (3,4), (5,6)))
# Output is a vector of arrays:
> ((1,3,5), (2,4,6))
# same results with splatting
collect(zip(arr...))
> ((1,3,5), (2,4,6))
Unpacking an array in python
You could simply transpose it before unpacking:
x, y, z = data.T
Unpacking "unpacks" the first dimensions of an array and by transposing the your array the size-3 dimension will be the first dimension. That's why it didn't work with [x, y, z] = data1[:, 0:3]
because that tried to unpack 1000 values into 3 variables.
How to unzip a list of tuples into individual lists?
Use zip(*list)
:
>>> l = [(1,2), (3,4), (8,9)]
>>> list(zip(*l))
[(1, 3, 8), (2, 4, 9)]
The zip()
function pairs up the elements from all inputs, starting with the first values, then the second, etc. By using *l
you apply all tuples in l
as separate arguments to the zip()
function, so zip()
pairs up 1
with 3
with 8
first, then 2
with 4
and 9
. Those happen to correspond nicely with the columns, or the transposition of l
.
zip()
produces tuples; if you must have mutable list objects, just map()
the tuples to lists or use a list comprehension to produce a list of lists:
map(list, zip(*l)) # keep it a generator
[list(t) for t in zip(*l)] # consume the zip generator into a list of lists
Related Topics
Creating a Test Suite Using Ruby Minitest
How to Convert Utf8 Combined Characters into Single Utf8 Characters in Ruby
Ruby Refuses to Divide Correctly
Exec': String Contains Null Byte (Argumenterror)
Detecting Overlapping Ranges in Ruby
How to Modify a Text File in Ruby
In Ruby How to Automatically Populate Instance Variables Somehow in the Initialize Method
2 Gems Need Different Versions of the Same Dependency
What's the Best Way to Implement Acls to a Rails Application
Converting an Array of Hashes to One Hash in Ruby
Sorting a Hash in Ruby by Its Value First Then Its Key
Ftps (Tls/Ssl) from Ruby on Rails App
How to Make Xcode Use the Correct Version of Ruby When Running a Script
Alphabetize Arabic and Japanese Text That Is in Unicode
Generate Array of Numbers That Fit to a Probability Distribution in Ruby
Is There an Equivalent of Array#Find_Index for the Last Index in Ruby