Добавление строк в датафрейм с помощью цикла .iterrows () for - PullRequest
0 голосов
/ 18 марта 2019

Предположим, у меня есть следующий фрейм данных:

     xx      yy      tt
0   2.8     1.0     1.0
1   85.0    4.48    6.5
2   2.1     8.0     1.0
3   8.0     1.0     0.0
4   9.0     2.54    1.64
5   5.55    7.25    3.15
6   1.66    0.0     4.0
7   3.0     7.11    1.98
8   1.0     0.0     4.65
9   1.87    2.33    0.0

Что я хочу с ним сделать, чтобы создать цикл for, который перебирает все точки в df и вычисляет евклидово расстояние до всех остальных точек. Например: цикл будет перебирать точку a и получать расстояния от точки a до точки b, c, d ... n. Затем он перейдет в точку b и получит расстояния до точек a, c, d ... n и т. Д.

Как только я получу расстояния, я хочу получить value_counts() значений расстояний, но ради экономии памяти я не могу просто value_counts() все результаты, которые я получаю из этого цикла foor, потому что мой реальный df слишком велик, и у меня закончится нехватка памяти.

Итак, я подумал, что нужно выполнить операцию value_counts() с вектором расстояния, это даст 2-колоночный массив данных со значениями и их соответствующими значениями, а затем, когда он перебирает точку b и получит все расстояния, я хочу сравнить новые значения с предыдущим value_counts() df из первого цикла и проверить, есть ли повторяющиеся значения, если да, то я хочу += счетчик повторных значений, если повторных значений не найдено, я хочу append() все эти строки без повторяющихся значений до расстояния DF.

Это то, что у меня так далеко:

import pandas as pd

counts = pd.DataFrame()

for index, row in df.iterrows():

    dist = pd.Series(np.sqrt((row.xx - df.xx)**2 + (row.yy - df.yy)**2 + (row.tt - df.tt)**2)) # Create a vector containing all the distances from each point to the others

    counter = pd.Series(dist.value_counts(sort = True)).reset_index().rename(columns = {'index': 'values', 0:'counts'}) # Get a counter for every value in the distances vector

    if index in counter['values']:
        counter['counts'][index] += 1 # Check if the new values are in the counter df, if so, add +1 to each repeated value

    else:

        counts = counts.append((index,row)) # If no repeated values, then append new rows to the counter df

Ожидаемый результат будет примерно таким:

# These are the value counts for point a and its distances:

    values  counts
0   0.000000    644589
1   0.005395    1
2   0.005752    1
3   0.016710    1
4   0.023043    1
5   0.012942    1
6   0.020562    1

Теперь в итерации по точке b:

       values   counts
0   0.000000    644595  # Value repeated 6 times, so add +6 to the counter
1   0.005395    1
2   0.005752    1
3   0.016710    3  # Value repeated twice, so add +2 to the counter
4   0.023043    1
5   0.012942    1
6   0.020562    1
7   0.025080    1  # New value, so append a new row with value and counter
8   0.022467    1  # New value, so append a new row with value and counter

Однако, если вы добавите print (counts) в конец цикла, чтобы проверить результаты того, что делает этот цикл, вы увидите пустой фрейм данных. И именно поэтому я задаю этот вопрос. Почему этот код дает пустой df, и как я могу заставить его работать так, как я хочу?

Если вам нужны дополнительные объяснения, что-то не понятно или вам нужна дополнительная информация, пожалуйста, не стесняйтесь спрашивать об этом.

Заранее спасибо

1 Ответ

1 голос
/ 18 марта 2019

если вас понимают, вы хотите, чтобы значения каждого расстояния встречались:

поэтому я предлагаю вам создать dict: ключи - это значения, а значения ключей - это количество:

data = """
   xx      yy      tt
2.8     1.0     1.0
85.0    4.48    6.5
2.1     8.0     1.0
8.0     1.0     0.0
9.0     2.54    1.64
5.55    7.25    3.15
1.66    0.0     4.0
3.0     7.11    1.98
1.0     0.0     4.65
1.87    2.33    0.0
"""

import pandas as pd
df = pd.read_csv(pd.compat.StringIO(data), sep='\s+')

dico ={}                            #i initialize the dict dico
for index, row in df.iterrows():
    dist = pd.Series(np.sqrt((row.xx - df.xx) ** 2 + (row.yy - df.yy) ** 2 + 
          (row.tt - df.tt) ** 2))   # Create a vector containing all the 
                                    #distances from each point to the others

    for f in dist:                  #i iterate through dist
        if f in dico:               #the key already exists in dict?
            dico[f] +=dico[f]       #yes i increment the value
        else:
            dico[f]=1               #no i create the key with the new distance and set to 1

print(dico)

выход:

{0.0: 512, 
82.45726408267497: 2, 
7.034912934784623: 2, 
5.295280917949491: 2, 
6.4203738208923635: 2, 
7.158735921934822: 2, 
3.361487765856065: 2, 
6.191324575565393: 2, 
4.190763653560053: 2, 
1.9062528688503002: 2, 
83.15678204452118: 2, 
77.35218419669867: 2, 
76.17993961667337: 2, 
79.56882492534372: 2, 
    :
    :
7.511863949779708: 2,
0.9263368717696604: 2, 
4.633896848226123: 2, 
7.853725230742415: 2, 
5.295819105671946: 2, 
5.273357564208974: 2}

каждое значение имеет по крайней мере 2 счета, потому что это кросс-таблица и расстояние (точка0 до точки1) равное расстояние (точка1 до точки0) ....

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...