Сохраните каждую строку pandas фрейма данных во временный фрейм данных - PullRequest
1 голос
/ 24 марта 2020

Я использую scipy для сравнения различных функций расстояния, используя данные, содержащиеся в pandas dataframes. Для справки я проверяю расстояние между различными деталями, которые производит моя компания.

(Это, очевидно, игрушечный пример для этого вопроса. Извините, если что-то не завершено, я пытаюсь сделать Минимальный, Воспроизводимый Пример )

У меня есть тестовый фрейм данных, x, который выглядит следующим образом:

| part_number | make_buy_M | make_buy_B | alternate_Y | alternate_N | value |
|:-----------:|:----------:|:----------:|:-----------:|:-----------:|:-----:|
|      A      |      1     |      0     |      0      |      1      |  1065 |

Затем у меня большой фрейм данных, data, который выглядит точно так же но содержит много частей:

| part_number | make_buy_M | make_buy_B | alternate_Y | alternate_N | value |
|:-----------:|:----------:|:----------:|:-----------:|:-----------:|:-----:|
|      B      |      1     |      0     |      0      |      1      |  982  |
|      C      |      0     |      1     |      0      |      1      |   87  |
|      D      |      1     |      0     |      0      |      1      |  2342 |
|      E      |      0     |      1     |      1      |      0      | 56233 |

У меня есть функция, которая перебирает scipy метрики расстояния. То, что я хотел бы сделать, это сравнить значение x с каждой строкой кадра данных и сохранить эти результаты в формате dict

import pandas as pd, numpy as np, scipy, gc as gc
from math import *
from decimal import Decimal
from scipy import spatial

# Resources:
#   - https://dataconomy.com/2015/04/implementing-the-five-most-popular-similarity-measures-in-python/
# Resources

def euclidean_distance(x, y):
    return sqrt(sum(pow(a-b,2) for a, b in zip(x, y)))  

def cosine_similarity(x,y):
    def square_rooted(x):
       return round(sqrt(sum([a*a for a in x])),3)

    numerator = sum(a*b for a,b in zip(x,y))
    denominator = square_rooted(x)*square_rooted(y)

    return round(numerator/float(denominator),3)

# Read in CSV
x = pd.read_csv('Test_Part_Directory')
y = pd.read_csv('Other_Parts_Directory')
metrics = ['cosine', 'euclidean']
euclidean_dict = {}
cosine_dict = {}


# How to loop through the y for this?

# for x in y.rows():
    # current_row = y[x]
    # Then do the below codes

for m in metrics:
    try:       
        curr = scipy.spatial.distance.cdist(x.iloc[:,:], y.iloc[:,:], metric=m)        
        print("Metric: {} | Score: {} ".format(m, curr))

        """
            Currently commented out
        if m == 'cosine':
            cosine_dict[part_number from dict] = curr
        else:
            euclidean_dict[part_number from dict] = curr
        """

    except:
        print("Error calculating {}".format(m))

В конечном счете, я ищу два кода, которые содержат ключевое значение пары: part_number: metric_score, что-то вроде:

Я написал этот код, который достигает текущей точки, но не eucliean_dict = {'B': 0.954, 'C': 0.233, 'D': 0.003, 'E': 0.012}

Я смотрел на этот вопрос , но это говорит мне, что не oop.

ОБНОВЛЕНИЕ - я попробовал следующее:

for index, row in data.iterrows():
    part_number = data['PART_NO'].iloc[0]
    y = row.drop('PART_NO', axis=1)
    for m in metrics:
        try:
            curr = scipy.spatial.distance.cdist(x.iloc[:,:], y.iloc[:,:], metric=m)
            print("Part Number: {} | Metric: {} | Score: {} ".format(part_number, m, curr))
        except:
            print("Error calculating {}".format(m))

Но получил:

Traceback (most recent call last):
  File "distance_function.py", line 95, in <module>
    y = row.drop('PART_NO', axis=1)
  File "C:\Python367-64\lib\site-packages\pandas\core\series.py", line 4139, in drop
    errors=errors,
  File "C:\Python367-64\lib\site-packages\pandas\core\generic.py", line 3923, in drop
    axis_name = self._get_axis_name(axis)
  File "C:\Python367-64\lib\site-packages\pandas\core\generic.py", line 420, in _get_axis_name
    raise ValueError(f"No axis named {axis} for object type {cls}")
ValueError: No axis named 1 for object type <class 'pandas.core.series.Series'>

ОБНОВЛЕНИЕ 2 - я попытался следующее:

part_number = data['PART_NO'].iloc[0]
temp = row.to_frame()
y = temp.drop('PART_NO', axis=1)

Все же я получаю ту же ошибку.

1 Ответ

0 голосов
/ 25 марта 2020

Кажется, что имена ваших столбцов теперь являются индексами. Итак, если вы хотите сбросить 'PART_NO', вы должны сделать это с axis=0:)

...