以更简单的方式创建一个 np.array,并传输到 csv
create a np.array in a simpler way, and transferring to csv
我正在寻找更简单的代码来创建以下数组:
[[1. 1. 1.]
[2. 1. 1.]
[3. 1. 1.]
[4. 1. 1.]
[1. 2. 1.]
[2. 2. 1.]
[3. 2. 1.]
[4. 2. 1.]
[1. 3. 1.]
[2. 3. 1.]
[3. 3. 1.]
[4. 3. 1.]
[1. 1. 2.]
[2. 1. 2.]
[3. 1. 2.]
[4. 1. 2.]
[1. 2. 2.]
[2. 2. 2.]
[3. 2. 2.]
[4. 2. 2.]
[1. 3. 2.]
[2. 3. 2.]
[3. 3. 2.]
[4. 3. 2.]]
我已经编写了以下代码来生成它,但绝对不是一个好代码。
import numpy as np
t1 = np.array([])
t2 = np.array([])
# creating the i column
for k in range (1,3):
for j in range(1,4):
x = np.array(list(range(1, 5)))
y = np.append(t1, x)
t1 = y
# creating the j column
for k in range(1,3):
x = np.array(list(range(1, 4)))
y = np.repeat(x, 4)
t2 = np.append(t2, y)
# creating the k column
x = np.array(list(range(1, 3)))
t3 = np.repeat(x, 3*4)
new = np.transpose(np.vstack((t1, t2, t3)))
此外,在下一步中,我想将其导出到 csv 文件,使这些数字以这种形状存在(我的意思是我在 csv 文件中的第一列包括:1,2,3,1, 2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3 等接下来的两列)
我尝试使用 numpy.savetxt()
但它似乎只适用于一维和二维数组。
有什么建议吗?
itertools.product 非常适合您的用例:
from itertools import product
import pandas as pd
X = sorted(list(product([1,2,3,4], [1,2,3], [1,2])), key=lambda x: (x[2], x[1], x[0]))
pd.DataFrame(X).to_csv('output.csv', header=False, index=False)
输出:
[[1, 1, 1], [2, 1, 1], [3, 1, 1], [4, 1, 1], [1, 2, 1], [2, 2, 1], [3, 2, 1], [4, 2, 1], [1, 3, 1], [2, 3, 1], [3, 3, 1], [4, 3, 1], [1, 1, 2], [2, 1, 2], [3, 1, 2], [4, 1, 2], [1, 2, 2], [2, 2, 2], [3, 2, 2], [4, 2, 2], [1, 3, 2], [2, 3, 2], [3, 3, 2], [4, 3, 2]]
您可以使用 itertools
模块创建数组,然后使用 pandas
轻松将其导出到 csv 文件:
import itertools
import pandas as pd
# create the array of all combinations you showed
arr = list(itertools.product([1,2,3,4], [1,2,3], [1,2]))
# output the array to a csv file:
df = pd.DataFrame(arr).to_csv('filename.csv', header=False, index=False)
虽然 itertools.product
可能是最好的(我也想探索使用 np.meshgrid
),但我们可以简化您的代码。
首先用列表理解制作 3 个列表。 np.append
重复使用会很慢。列表附加更好,但列表理解更紧凑。
In [94]: t1 = [np.arange(1,5) for k in range(2) for j in range(3)]
...: t2 = [np.repeat(np.arange(1,4),4) for k in range(2)]
...: t3 = np.repeat(np.arange(1,3), 3*4)
现在看看结果。值在那里,但形状不太正确。
In [95]: t1
Out[95]:
[array([1, 2, 3, 4]),
array([1, 2, 3, 4]),
array([1, 2, 3, 4]),
array([1, 2, 3, 4]),
array([1, 2, 3, 4]),
array([1, 2, 3, 4])]
In [96]: t2
Out[96]:
[array([1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3]),
array([1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3])]
In [97]: t3
Out[97]:
array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2])
但我们可以将它们压平。 np.ravel
会将列表转换为数组并将其展平。
In [98]: np.ravel(t1)
Out[98]:
array([1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2,
3, 4])
现在我们可以加入 stack
。这就像 vstack
但让我们控制连接轴。
In [99]: np.stack((np.ravel(t1), np.ravel(t2), t3), axis=1)
Out[99]:
array([[1, 1, 1],
[2, 1, 1],
[3, 1, 1],
[4, 1, 1],
[1, 2, 1],
[2, 2, 1],
[3, 2, 1],
[4, 2, 1],
[1, 3, 1],
...
[3, 3, 2],
[4, 3, 2]])
因为它是 2d,savetxt
就可以了:
In [100]: np.savetxt('test', Out[99], fmt='%5d')
In [101]: cat test
1 1 1
2 1 1
3 1 1
4 1 1
1 2 1
...
===
itertools.product
生成正确的元组,但顺序相反:
In [108]: alist = list(itertools.product(range(1,3), range(1,4), range(1,5)))
In [109]: alist
Out[109]:
[(1, 1, 1),
(1, 1, 2),
(1, 1, 3),
(1, 1, 4),
...
(2, 2, 4),
(2, 3, 1),
(2, 3, 2),
(2, 3, 3),
(2, 3, 4)]
但是当我们创建一个数组时,这很容易改变:
In [110]: np.array(alist)[:,::-1]
Out[110]:
array([[1, 1, 1],
[2, 1, 1],
[3, 1, 1],
[4, 1, 1],
[1, 2, 1],
...
[4, 2, 2],
[1, 3, 2],
[2, 3, 2],
[3, 3, 2],
[4, 3, 2]])
===
另一种选择 - meshgrid
:
In [111]: x,y,z = np.meshgrid(np.arange(1,3), np.arange(1,4), np.arange(1,5), indexing='ij')
In [112]: x.shape
Out[112]: (2, 3, 4)
In [113]: y.shape
Out[113]: (2, 3, 4)
In [114]: x.ravel()
Out[114]:
array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2])
In [115]: y.ravel()
Out[115]:
array([1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3,
3, 3])
In [116]: z.ravel()
Out[116]:
array([1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2,
3, 4])
In [117]: np.stack([z.ravel(), y.ravel(), x.ravel()], axis=1)
Out[117]:
array([[1, 1, 1],
[2, 1, 1],
[3, 1, 1],
[4, 1, 1],
[1, 2, 1],
....
另一种组合 3 个数组的方法:
np.stack((z,y,x), axis=3).reshape(-1,3)
stack
步骤生成一个 (2, 3, 4, 3) 数组。
===
另一种方法(不解释):
arr = np.mgrid[1:3, 1:4, 1:5]
arr.transpose(1,2,3,0).reshape(-1,3)[:,::-1]
我正在寻找更简单的代码来创建以下数组:
[[1. 1. 1.]
[2. 1. 1.]
[3. 1. 1.]
[4. 1. 1.]
[1. 2. 1.]
[2. 2. 1.]
[3. 2. 1.]
[4. 2. 1.]
[1. 3. 1.]
[2. 3. 1.]
[3. 3. 1.]
[4. 3. 1.]
[1. 1. 2.]
[2. 1. 2.]
[3. 1. 2.]
[4. 1. 2.]
[1. 2. 2.]
[2. 2. 2.]
[3. 2. 2.]
[4. 2. 2.]
[1. 3. 2.]
[2. 3. 2.]
[3. 3. 2.]
[4. 3. 2.]]
我已经编写了以下代码来生成它,但绝对不是一个好代码。
import numpy as np
t1 = np.array([])
t2 = np.array([])
# creating the i column
for k in range (1,3):
for j in range(1,4):
x = np.array(list(range(1, 5)))
y = np.append(t1, x)
t1 = y
# creating the j column
for k in range(1,3):
x = np.array(list(range(1, 4)))
y = np.repeat(x, 4)
t2 = np.append(t2, y)
# creating the k column
x = np.array(list(range(1, 3)))
t3 = np.repeat(x, 3*4)
new = np.transpose(np.vstack((t1, t2, t3)))
此外,在下一步中,我想将其导出到 csv 文件,使这些数字以这种形状存在(我的意思是我在 csv 文件中的第一列包括:1,2,3,1, 2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3 等接下来的两列)
我尝试使用 numpy.savetxt()
但它似乎只适用于一维和二维数组。
有什么建议吗?
itertools.product 非常适合您的用例:
from itertools import product
import pandas as pd
X = sorted(list(product([1,2,3,4], [1,2,3], [1,2])), key=lambda x: (x[2], x[1], x[0]))
pd.DataFrame(X).to_csv('output.csv', header=False, index=False)
输出:
[[1, 1, 1], [2, 1, 1], [3, 1, 1], [4, 1, 1], [1, 2, 1], [2, 2, 1], [3, 2, 1], [4, 2, 1], [1, 3, 1], [2, 3, 1], [3, 3, 1], [4, 3, 1], [1, 1, 2], [2, 1, 2], [3, 1, 2], [4, 1, 2], [1, 2, 2], [2, 2, 2], [3, 2, 2], [4, 2, 2], [1, 3, 2], [2, 3, 2], [3, 3, 2], [4, 3, 2]]
您可以使用 itertools
模块创建数组,然后使用 pandas
轻松将其导出到 csv 文件:
import itertools
import pandas as pd
# create the array of all combinations you showed
arr = list(itertools.product([1,2,3,4], [1,2,3], [1,2]))
# output the array to a csv file:
df = pd.DataFrame(arr).to_csv('filename.csv', header=False, index=False)
虽然 itertools.product
可能是最好的(我也想探索使用 np.meshgrid
),但我们可以简化您的代码。
首先用列表理解制作 3 个列表。 np.append
重复使用会很慢。列表附加更好,但列表理解更紧凑。
In [94]: t1 = [np.arange(1,5) for k in range(2) for j in range(3)]
...: t2 = [np.repeat(np.arange(1,4),4) for k in range(2)]
...: t3 = np.repeat(np.arange(1,3), 3*4)
现在看看结果。值在那里,但形状不太正确。
In [95]: t1
Out[95]:
[array([1, 2, 3, 4]),
array([1, 2, 3, 4]),
array([1, 2, 3, 4]),
array([1, 2, 3, 4]),
array([1, 2, 3, 4]),
array([1, 2, 3, 4])]
In [96]: t2
Out[96]:
[array([1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3]),
array([1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3])]
In [97]: t3
Out[97]:
array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2])
但我们可以将它们压平。 np.ravel
会将列表转换为数组并将其展平。
In [98]: np.ravel(t1)
Out[98]:
array([1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2,
3, 4])
现在我们可以加入 stack
。这就像 vstack
但让我们控制连接轴。
In [99]: np.stack((np.ravel(t1), np.ravel(t2), t3), axis=1)
Out[99]:
array([[1, 1, 1],
[2, 1, 1],
[3, 1, 1],
[4, 1, 1],
[1, 2, 1],
[2, 2, 1],
[3, 2, 1],
[4, 2, 1],
[1, 3, 1],
...
[3, 3, 2],
[4, 3, 2]])
因为它是 2d,savetxt
就可以了:
In [100]: np.savetxt('test', Out[99], fmt='%5d')
In [101]: cat test
1 1 1
2 1 1
3 1 1
4 1 1
1 2 1
...
===
itertools.product
生成正确的元组,但顺序相反:
In [108]: alist = list(itertools.product(range(1,3), range(1,4), range(1,5)))
In [109]: alist
Out[109]:
[(1, 1, 1),
(1, 1, 2),
(1, 1, 3),
(1, 1, 4),
...
(2, 2, 4),
(2, 3, 1),
(2, 3, 2),
(2, 3, 3),
(2, 3, 4)]
但是当我们创建一个数组时,这很容易改变:
In [110]: np.array(alist)[:,::-1]
Out[110]:
array([[1, 1, 1],
[2, 1, 1],
[3, 1, 1],
[4, 1, 1],
[1, 2, 1],
...
[4, 2, 2],
[1, 3, 2],
[2, 3, 2],
[3, 3, 2],
[4, 3, 2]])
===
另一种选择 - meshgrid
:
In [111]: x,y,z = np.meshgrid(np.arange(1,3), np.arange(1,4), np.arange(1,5), indexing='ij')
In [112]: x.shape
Out[112]: (2, 3, 4)
In [113]: y.shape
Out[113]: (2, 3, 4)
In [114]: x.ravel()
Out[114]:
array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2])
In [115]: y.ravel()
Out[115]:
array([1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3,
3, 3])
In [116]: z.ravel()
Out[116]:
array([1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2,
3, 4])
In [117]: np.stack([z.ravel(), y.ravel(), x.ravel()], axis=1)
Out[117]:
array([[1, 1, 1],
[2, 1, 1],
[3, 1, 1],
[4, 1, 1],
[1, 2, 1],
....
另一种组合 3 个数组的方法:
np.stack((z,y,x), axis=3).reshape(-1,3)
stack
步骤生成一个 (2, 3, 4, 3) 数组。
===
另一种方法(不解释):
arr = np.mgrid[1:3, 1:4, 1:5]
arr.transpose(1,2,3,0).reshape(-1,3)[:,::-1]