2015-02-13 4 views
-1

Как вернуть DataFrame из объекта groupby с помощью Pandas? Цель здесь - прочитать в CSV и заменить каждый IP-адрес в столбце IP-адреса значением, возвращаемым randIP(). Я хотел бы сделать это, группируя, чтобы поддерживать согласованность во всем запутанном фрейме данных (каждый реальный IP-карты для нового случайного IP-адреса).Применить функцию к Dataframe GroupBy Объект и возвращаемый dataframe

Я пробовал множество методов, но это кажется самым успешным. self.df2 печатает как объект pandas.core.grouby.SeriesGroupBy.

def __init__(self, filename): 
    self.df = pd.read_csv(filename) 
    self.grouped = self.df.groupby('IP Address') 
    self.df.reset_index(drop=True, inplace=True) 
    for i, k in self.grouped: 
     r = randIP() 
     k['IP Address'] = k['IP Address'].apply(lambda x: x.replace(x, r)) 
    self.df2 = self.grouped 
    print(self.df2['IP Address']) 
+0

Вы говорите, что у вас есть DataFrame с столбцом «IP-адрес», и вы хотите вернуть тот же DataFrame, но с измененным этим столбцом? Есть ли другой текст в столбце «IP-адрес» помимо IP-адреса? – BrenBarn

+0

Это правильно. У меня есть столбец только IP-адресов, которые я бы хотел заменить в групповом режиме и вернуть в конце модифицированный (полный) кадр данных. – user3764070

ответ

0

Лучше не пытаться модифицировать DataFrame изнутри операции группировки. Вместо этого следует использовать группировку операции создать новые IP-адрес, а затем использовать map для отображения старых IP-адресов на новые, а затем (если вы хотите) назначить новые обратно в DataFrame:

def randomIP(): 
    return ".".join(str(np.random.randint(0, 255) for it in xrange(4))) 

>>> d = pandas.DataFrame({'IP': ['1.2.3.4', '5.6.7.8', '1.2.3.4', '5.6.7.8', '9.10.11.12', '13.14.15.16'], 'Other': ['blah']*6}) 
>>> d 
      IP Other 
0  1.2.3.4 blah 
1  5.6.7.8 blah 
2  1.2.3.4 blah 
3  5.6.7.8 blah 
4 9.10.11.12 blah 
5 13.14.15.16 blah 

Использование groupby с apply даст вам отображение серии старых к новым IP-адресов:

>>> d.groupby('IP').apply(lambda g: randomIP()) 
IP 
1.2.3.4   4.183.193.46 
13.14.15.16 186.124.189.188 
5.6.7.8   152.24.105.42 
9.10.11.12  188.140.91.209 

Использование map на старой колонке IP и передачи этой новой серии будет отображать старые IP-адреса на новые IP-адреса:

>>> d.IP.map(d.groupby('IP').apply(lambda g: randomIP())) 
0 47.227.125.190 
1  164.86.98.48 
2 47.227.125.190 
3  164.86.98.48 
4  44.150.90.127 
5  71.111.59.115 
Name: IP, dtype: object 

Если вы хотите переназначить их обратно в колонну DataFrame, вы можете сделать это:

>>> d['IP'] = d.IP.map(d.groupby('IP').apply(lambda g: randomIP())) 
>>> d 
       IP Other 
0 238.227.204.61 blah 
1 13.201.160.89 blah 
2 238.227.204.61 blah 
3 13.201.160.89 blah 
4 69.33.243.79 blah 
5 164.120.13.218 blah 

Я думаю, что это последнее является все-в-одном, что вы ищете. (В этих примерах случайные IP-адреса различаются каждый раз, потому что я снова вызываю randomIP в каждой части примера.)

+0

Последний пример - _perfect_, а те, что над ним, очень иллюстрируют, почему он работает так, как он делает. Спасибо! – user3764070