0
$\begingroup$

I have a Pandas DataFrame (from CSV) like that:

enter image description here

I want to group by "Slice_ID" column and I succeeded in making each group with equal rows, so I now have many groups of the same length.

I want to make a grid object for each column (other than Slice_ID) that Z will be the value in the column (Force for example), X will be the Slice_ID value and Y will be the index of each group.

How can I make such a thing?

$\endgroup$
2
  • $\begingroup$ it's in the documentation how to group by column: pandas.pydata.org/docs/reference/api/… $\endgroup$
    – Harry McKenzie
    Commented Aug 15, 2022 at 2:27
  • 1
    $\begingroup$ Thanks, @HarryMcKenzie, I know how to do that but do not know how to visualize the column as a grid object. $\endgroup$ Commented Aug 15, 2022 at 13:02

1 Answer 1

1
$\begingroup$

enter image description here

You don't actually need to do any groupby here, since it will simply select for you the rows that match a certain Slice_ID, but less explicitly.

I'll demosntrate a solution with a randomly generated dataframe similar to what you've described and shown. It has a Slice_ID column, and 5 other columns with random values, like this:

>>> df
    Slice_ID         A         B         C         D         E         F
0          0  0.100073  0.179458  0.540679  0.942569  0.816452  0.191535
1          1  0.973071  0.944476  0.071374  0.937174  0.126977  0.384772
2          2  0.101452  0.157549  0.952695  0.626640  0.108958  0.983997
3          3  0.297725  0.541563  0.721508  0.002660  0.122507  0.504464
4          4  0.307248  0.697413  0.143758  0.043016  0.828669  0.600739
..       ...       ...       ...       ...       ...       ...       ...
95         0  0.601100  0.965037  0.135574  0.303758  0.756496  0.247544
96         1  0.825840  0.764913  0.933467  0.861191  0.751876  0.454644
97         2  0.964023  0.189546  0.149951  0.007895  0.635078  0.904698
98         3  0.973948  0.301643  0.735600  0.981501  0.187780  0.575356
99         4  0.751616  0.941617  0.404419  0.340134  0.656586  0.509154

Here's a solution that follows what you suggest you're aiming for:

import bpy
import pandas as pd
import numpy as np
import bmesh

#fp = 'mypath/myfile.csv'
#df = pd.read_csv(fp)

# Create random dataframe with n groups groups (Slice_ID) of m values per group, and random values in cols A-F
n = 5  # number of groups
m = 20 # number of items per group
df = pd.DataFrame({ 'Slice_ID' : list(range(n))*m })
for c in 'ABCDEF':
    df.loc[:, c] = np.random.random(size=m*n)
    
# Iterate over each group and create a grid
# You don't need groupby to do this, since you can just select each group by its Slice_ID
for sid in df['Slice_ID'].unique():
    slice_df = df[ df['Slice_ID'] == sid ]
    x = sid
    y = np.arange(len(slice_df)) # The pandas index will not help you here, so we'll generate an int range
        
    # Iterate over each column from the 2nd col and up
    for col in slice_df.columns[1:]:
        bm = bmesh.new()
        gridcols = int(len(slice_df)/n)
        bmesh.ops.create_grid(bm, x_segments=n-1, y_segments=gridcols-1, size=n*gridcols/10)
        
        bm.verts.ensure_lookup_table()
        for v, z in zip( bm.verts, slice_df[col].values ):
            v.co.z = z
        
        mesh = bpy.data.meshes.new(f'Grid_{col}')
        bm.to_mesh(mesh)
        obj  = bpy.data.objects.new(f'Grid_{col}', mesh)
        bpy.context.scene.collection.objects.link(obj)
        

A single slice looks like this: enter image description here

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .