Replikacja wartosci z jednej kolumny do innych

0

Cześć!

Wracam do pythona po długiej przerwie, mam problem z bardzo prostym taskiem, więc sorry za poziom.
Mam matrycę, (115 rzędów i 531 kolumn). W rzędach mam wartości od 0 do 3ch.
Chciałbym zastąpić wszystkie wartości, które są wieksze od 0 nazwami rzędów (czyli z kolumny 0).

Rozbijam ten task na 3 czesci:

  1. Przeiteruj po zbiorze - for i in dataset:
  2. Znajdz wartosci wieksze niz 0 - if i>0
  3. przepisz nazwe rzedu - tu się potykam, będe wdzięczny za sugestie jak te nazwy rzedow zreplikowac. Próbowałem przypisać je do innej zmiennej i wkleić, ale wynik jest bez sensu

poczatek:
dataset=dataset[for i in dataset: if i>0, ]

screenshot-20220405101614.png

0

Masz jakiś kod?

0

na razie tylko
data=data.fillna(0, inplace=True) - zamienilem NaN na zera
i w sumie ostatnią operacją, jaka chce zrobic na tym secie to własnie ta zaieniająca wartosci z 1wszej kolumny.
No i nie chcialem zasmiecac forum nieudanymi probami, wiec wkleilem tylko dataset=dataset[for i in dataset: if i>0, ],

0

A po co Ci indeksy wierszy jako wartości?

import numpy as np
import pandas as pd

# test data preparation
ROW_COUNT: int = 7
COL_COUNT: int = 3

matrix = np.reshape(np.random.randint(low=0, high=3, size=ROW_COUNT * COL_COUNT), (ROW_COUNT, COL_COUNT))

df = pd.DataFrame(matrix)

df.index = [f"Row_{i}" for i in range(ROW_COUNT)]
df.columns = [f"Col_{i}" for i in range(COL_COUNT)]

# transformation 
df['ROW_NAME'] = df.index
after_application = df.apply(lambda row: [row[-1] if x != 0 else x for x in row], axis=1)

print(df)
print(after_application)

Konstrukcja prosta:
a) dorzucamy kolumnę z nazwą wiersza
b) aplikujemy lambdę po AXIS=1 (czyli w wierszu)

Przykładowy wynik:

       Col_0  Col_1  Col_2 ROW_NAME
Row_0      2      1      2    Row_0
Row_1      1      0      2    Row_1
Row_2      2      0      1    Row_2
Row_3      0      2      0    Row_3
Row_4      2      2      2    Row_4
Row_5      2      0      2    Row_5
Row_6      1      0      1    Row_6
Row_0    [Row_0, Row_0, Row_0, Row_0]
Row_1        [Row_1, 0, Row_1, Row_1]
Row_2        [Row_2, 0, Row_2, Row_2]
Row_3            [0, Row_3, 0, Row_3]
Row_4    [Row_4, Row_4, Row_4, Row_4]
Row_5        [Row_5, 0, Row_5, Row_5]
Row_6        [Row_6, 0, Row_6, Row_6]
dtype: object
0

Dzięki! Mój błąd, wrzuciłem dane z excela, a nie z ramki danych - staram się przepisać wartosci z pierwszej kolumny do innych rzedow, w ktorych wartos komorki jest wieksza od 0. Popróbuje jeszcze z loopami i dam znać jak wyszło

0

@m345: wydaje mi się, że można dużo lepiej... używając numpy.

import numpy as np
import pandas as pd

ROW_COUNT: int = 7
COL_COUNT: int = 3

MATRIX_SIZE = ROW_COUNT * COL_COUNT
MATRIX_SHAPE = (ROW_COUNT, COL_COUNT)
VECTOR_SHAPE = (1, MATRIX_SIZE)

# test data preparation
matrix = np.random.randint(low=0, high=3, size=MATRIX_SIZE).astype('str').reshape(MATRIX_SHAPE)

df = pd.DataFrame(matrix)
df.index = [f"Row_{i}" for i in range(ROW_COUNT)]
df.columns = [f"Col_{i}" for i in range(COL_COUNT)]

# transformation
row_names = np.array(df.index).repeat(COL_COUNT).reshape(VECTOR_SHAPE)
elements = matrix.reshape(VECTOR_SHAPE)

updated_matrix = np.where(elements != '0',
                          row_names,
                          elements).reshape(MATRIX_SHAPE)

updated_df = pd.DataFrame(updated_matrix)
updated_df.index = [f"Row_{i}" for i in range(ROW_COUNT)]
updated_df.columns = [f"Col_{i}" for i in range(COL_COUNT)]

print(df)
print(updated_df)

Dla małych macierzy pewnie nie ma to znaczenia, dla 10k x 10k:

  • numpy - ~11 sekund
  • apply - ~210 sekund

Można jeszcze się bawić wydajnościowo i zamiast nazw indeksów (Row_0,Row_1, ...), zapisać wartość będącą indeksem do nazw wierszy + użyć w numpy typu danych 'int8' (dzięki temu obiekt będzie zajmował mniej pamięci) -> wykonanie (dla macierzy 10kx10k)-> 0.5 sekundy

1 użytkowników online, w tym zalogowanych: 0, gości: 1