Использование значений списка, хранящегося в ячейке DataFrame в Pandas - PullRequest
0 голосов
/ 10 октября 2018

У меня есть CSV-файл с каждым значением ячейки, состоящим из двух элементов (пары).

    |   0       |   1        |    2    | 
----------------------------------------
0   |[87, 1.03] | [30, 4.05] |   NaN   |
1   |[34, 2.01] |   NaN      |   NaN   |
2   |[83, 0.2]  | [18, 3.4]  |   NaN   |

Как мне получить доступ к их элементам отдельно?Первый элемент каждой пары действует как индекс для другой таблицы CSV.Я сделал что-то вроде этого, но это заставляет меня беспокоиться об одном или другом.

links = pd.read_csv('buslinks.csv', header = None)
a_list = []
for i in range(0, 100):
    l = []
    a_list.append(l)
for j in range(0, 100):
    a = busStops.iloc[j]
    df = pd.DataFrame(columns = ['id', 'Distance'])
    l = links.iloc[j]
    for i in l:
        if(pd.isnull(i)):
            continue
        else:
            x = int(i[0])
            d = busStops.iloc[x-1]
            id = d['id']
            dist = distance(d['xCoordinate'], a['xCoordinate'], d['yCoordinate'], a['yCoordinate'])
            df.loc[i] = [id, dist]
    a_list[j] = (df.sort('Distance', ascending = True)).tolist()

Этот подход работал, когда каждая ячейка содержала только один элемент.В этом случае np.isnan () использовался вместо pd.isnull ()

Файл CSV для чтения был создан как:

a_list = []
for i in range(0, 100):
    l = []
    a_list.append(l)
for i in range(0, 100):
    while(len(a_list[i])<3):
        x = random.randint(1, 100)
        if(x-1 == i):
             continue
        a = busStops.iloc[i]
        b = busStops.iloc[x-1]
        dist = distance(a['xCoordinate'], b['xCoordinate'], a['yCoordinate'], b['yCoordinate'])
        if dist>3:
            continue
        if x in a_list[i]:
            continue
        a_list[i].append([b['id'], dist])
        a_list[x-1].append([a['id'], dist])
    for j in range(0, 3):
        y = random.randint(0, 1)
        while (y == 0):
            x = random.randint(1, 100)
            if(x-1 == i):
                 continue
            a = busStops.iloc[i]
            b = busStops.iloc[x-1]
            dist = distance(a['xCoordinate'], b['xCoordinate'], a['yCoordinate'], b['yCoordinate'])
            if dist>3:
                continue
            if x in a_list[i]:
                continue
            a_list[i].append([b['id'], dist])
            a_list[x-1].append([a['id'], dist])
            y = 1
dfLinks = pd.DataFrame(a_list)
dfLinks
dfLinks.to_csv('buslinks.csv', index = False, header = False) 

BusStops - еще один файл CSV, который содержитid, xCoordinate, yCoordinate, Population и Priority в виде столбцов.

Ответы [ 2 ]

0 голосов
/ 10 октября 2018

Вы не должны помещать списки в pd.Series объекты.Это неэффективно, и вы теряете всю векторизованную функциональность.Однако, если вы решили, что эта должна быть вашей отправной точкой, вы можете распутать списки в несколько столбцов за пару шагов.

Настройка

df = pd.DataFrame({0: [[87, 1.03], [34, 2.01], [83, 0.2]],
                   1: [[30, 4.05], np.nan, [18, 3.4]],
                   2: [np.nan, np.nan, np.nan]})

Шаг 1: убедитесь, что списки имеют одинаковый размер

# messy way to ensure all values have length 2
df[1] = np.where(df[1].isnull(), pd.Series([[np.nan, np.nan]]*len(df[1])), df[1])

print(df)

            0           1   2
0  [87, 1.03]  [30, 4.05] NaN
1  [34, 2.01]  [nan, nan] NaN
2   [83, 0.2]   [18, 3.4] NaN

Шаг 2: объединить кадры данных разделенных серий

# create list of dataframes
L = [pd.DataFrame(df[col].values.tolist()) for col in df]

# concatenate dataframes in list
df_new = pd.concat(L, axis=1, ignore_index=True)

print(df_new)

    0     1     2     3   4
0  87  1.03  30.0  4.05 NaN
1  34  2.01   NaN   NaN NaN
2  83  0.20  18.0  3.40 NaN

Затем вы можете получить доступ к значениям, как обычно, например, df_new[2].

0 голосов
/ 10 октября 2018

Прежде всего, помните, что хранение списков в DataFrames обрекает вас на циклы Python-speed.Чтобы воспользоваться преимуществами быстрых подпрограмм Pandas / NumPy, вам нужно использовать нативные dtypes NumPy, такие как np.float64 (тогда как список, напротив, требует dtype «object»).

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

import pandas as pd

table = pd.DataFrame(columns=['col1', 'col2', 'col3'])
table.loc[0] = [1, 2,3]
table.loc[1] = [1, [2,3], 4]

table.loc[1].iloc[1]        # returns [2, 3]
table.loc[1].iloc[1][0]     # returns 2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...