2016-03-02 5 views
4

У меня есть DataFrame, который выглядит, как этотЗаполнение DataFrame с уникальными положительными целыми числами

col1 col2 col3 col4 col5 
0 0 1 0  1  1 
1 0 1 0  0  1 

Я хочу, чтобы присвоить уникальное положительное целое число больше 1, к каждой 0 записи.

поэтому я хочу DataFrame, который выглядит, как этот

 col1 col2 col3 col4 col5  
    0 2 1  3  1 1 
    1 4 1  5  6 1 

Целые не должен быть из упорядоченной последовательности, только положительной и уникальной.

ответ

3

np.arange(...).reshape(df.shape) генерирует dataframe SIVE из df, состоящий из непрерывных чисел, начиная с 2.

df.where(df, ...) работ, потому что ваш dataframe состоит из двоичных индикаторов (нулей и единиц). Он сохраняет все истинные значения (т. Е. Те), а затем использует непрерывный массив numpy для заполнения нулей.

# optional: inplace=True 
>>> df.where(df, np.arange(start=2, stop=df.shape[0] * df.shape[1] + 2).reshape(df.shape)) 
    col1 col2 col3 col4 col5 
0  2  1  4  1  1 
1  7  1  9 10  1 
2

Я думаю, что вы можете использовать numpy.arange для генерации уникальных случайных чисел с shape и заменить все 0 булевой генерацией маски на df == 0:

print df 
    col1 col2 col3 col4 col5 
0  0  1  0  1  1 
1  0  1  0  0  1 

print df == 0 
    col1 col2 col3 col4 col5 
0 True False True False False 
1 True False True True False 

print df.shape 
(2, 5) 

#count of integers 
min_count = df.shape[0] * df.shape[1] 
print min_count 
10 

#you need add 2, because omit 0 and 1 
print np.arange(start=2, stop=min_count + 2).reshape(df.shape) 
[[ 2 3 4 5 6] 
[ 7 8 9 10 11]] 

#use integers from 2 to max count of values of df 
df[ df == 0 ] = np.arange(start=2, stop=min_count + 2).reshape(df.shape) 
print df 
    col1 col2 col3 col4 col5 
0  2  1  4  1  1 
1  7  1  9 10  1 

Или использовать numpy.random.choice для больших уникальных случайных чисел:

#count of integers 
min_count = df.shape[0] * df.shape[1] 
print min_count 
10 
#you can use bigger number in np.arange, e.g. 100, but minimal is min_count + 2 
df[ df == 0 ] = np.random.choice(np.arange(2, 100), replace=False, size=df.shape) 
print df 
    col1 col2 col3 col4 col5 
0 17  1 53  1  1 
1 39  1 15 76  1 
+1

Это не гарантирует уникальность. Вы можете выбрать одно и то же случайное число. – Alexander

+0

@ Александр - вы правы. Я редактирую ответ. Спасибо. – jezrael

0

Это будет работать, хотя это не самая высокая производительность в пандах:

import random 

MAX_INT = 100 

for row in df: 
    for col in row: 
     if col == 0: 
      col == random.randrange(1, MAX_INT) 

Что-то вроде itertuples() будет быстрее, но если данных не так много, это нормально.

0
df[df == 0] = np.random.choice(np.arange(2, df.size + 2), replace=False, size=df.shape) 

Лот уже хорошие ответы здесь, но метательные это там.

  1. replace указывает, является ли образец с заменой или без замены.

  2. np.arange от (2, size of the df + 2). Это 2 потому, что вы хотите больше, чем 1.

  3. size должна быть такой же формы, как df, так что я просто использовал df.shape

Чтобы проиллюстрировать, что массив значений np.random.choice генерирует:

>>> np.random.choice(np.arange(2, df.size + 2), replace=False, size=df.shape) 
array([[11, 4, 6, 5, 9], 
     [ 7, 8, 10, 3, 2]]) 

Обратите внимание, что все они больше 1 и все они уникальны.

До:

col1 col2 col3 col4 col5 
0  0  1  0  1  1 
1  0  1  0  0  1 

После:

col1 col2 col3 col4 col5 
0  9  1  7  1  1 
1  6  1  3 11  1 
Смежные вопросы