Reputation: 131
Supposing I have the following matrix, either pandas
or numpy
:
A = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
I am looking for a way to reshape this array to 1D and keep the index of that cell as a column name so that if the above was to be flattened, the outcome would be as such:
>>> array([['i1j1', 'i1j2', 'i1j3', 'i2j1', 'i2j2', 'i2j3', 'i3j1', 'i3j2','i3j3'],
['1', '2', '3', '4', '5', '6', '7', '8', '9']], dtype='<U4')
Many thanks.
Upvotes: 1
Views: 704
Reputation: 8778
Here is another way:
b = (pd.DataFrame(A)
.rename(lambda x: 'i{}'.format(x+1))
.rename(lambda x: 'j{}'.format(x+1),axis=1)
.stack())
b = b.set_axis(b.index.map(''.join)).to_frame().T
Upvotes: 1
Reputation: 2174
as you noticed, there is a very intuitive way to calculate the indices of the flattened array. We can use np.meshgrid
to take advantage of that.
xv, yv = np.meshgrid(np.arange(A.shape[0]), np.arange(A.shape[1]))
indices = np.stack(( yv.flatten(), xv.flatten()), axis=1)
outputs
array([[0, 0],
[0, 1],
[0, 2],
[1, 0],
[1, 1],
[1, 2],
[2, 0],
[2, 1],
[2, 2]])
Edit:
To get the exact format you have in your example, try:
xv, yv = np.meshgrid(np.arange(A.shape[0]) + 1, np.arange(A.shape[1]) + 1)
rows = np.char.add('i', yv.flatten().astype(str))
cols = np.char.add('j', xv.flatten().astype(str))
indicies = np.char.add(rows,cols)
np.stack((indicies, A.flatten()))
returns
array([['i1j1', 'i1j2', 'i1j3', 'i2j1', 'i2j2', 'i2j3', 'i3j1', 'i3j2', 'i3j3'],
['1', '2', '3', '4', '5', '6', '7', '8', '9']], dtype='<U24')
Upvotes: 0
Reputation: 153510
Try:
df = pd.DataFrame(A,
columns=[f'j{j+1}' for j in range(A.shape[1])],
index=[f'i{i+1}' for i in range(A.shape[0])]).stack()
df.index = [f'{i}{j}' for i, j in df.index]
df_out = df.to_frame().T
df_out
Output:
i1j1 i1j2 i1j3 i2j1 i2j2 i2j3 i3j1 i3j2 i3j3
0 1 2 3 4 5 6 7 8 9
Upvotes: 2