Разбор и редактирование CSV с пандами - PullRequest
0 голосов
/ 29 ноября 2018

Я пытаюсь проанализировать все ячейки в CSV-файле, которые представляют высоты и округлять то, что следует после десятичной точки, чтобы соответствовать числу в списке (чтобы округлить до ближайшего дюйма).После нескольких дней удара головой о стену я смог получить код, который я смог получить:

import math
import pandas as pd

inch = [.0, .08, .16, .25, .33, .41, .50, .58, .66, .75, .83, .91, 1]

df = pd.read_csv("sample_csv.csv")


def to_number(s):
    for index, row in df.iterrows():
        try:
            num = float(s)
            num = math.modf(num)
            num = list(num)
            for i,j in enumerate(inch):
                if num[0] < j:
                    num[0] = inch[i-1]
                    break

                elif num[0] == j:
                    num[0] = inch[i]
                    break
            newnum = num[0] + num[1]
            return newnum
        except ValueError:
            return s


df = df.apply(lambda f : to_number(f[0]), axis=1).fillna('')
with open('new.csv', 'a') as f:
    df.to_csv(f, index=False)

В идеале мне бы хотелось, чтобы он анализировался по всему CSV с n заголовками., игнорируя все строки и округляя поплавки, чтобы соответствовать списку.Есть ли простой (r) способ достичь этого с помощью панд?И было бы возможно (или хорошая идея?), Чтобы это отредактировало существующую книгу Excel вместо создания нового CSV, который я должен был бы скопировать / вставить?

Любая помощь или предложения будут очень признательныпоскольку я очень новичок в Пандах, и это чертовски страшно!

Ответы [ 2 ]

0 голосов
/ 29 ноября 2018

Добавление к другому ответу для решения вашей проблемы со строками:

# Break the dataframe with a string
df = pd.DataFrame(np.random.uniform(5.1, 6.9, size=(10,3)))
df.ix[0,0] = 'str'

# Find out which things can be cast to numerics and put NaNs everywhere else
df_safe = df.apply(pd.to_numeric, axis=0, errors="coerce")
df_safe = (np.fix(df_safe) + np.round(12*(df_safe - np.fix(df_safe)))/12).round(2)

# Replace all the NaNs with the original data
df_safe[df_safe.isnull()] = df[df_safe.isnull()]

df_safe должно быть тем, что вы хотите.Несмотря на название, это не особенно безопасно, и, возможно, существуют крайние условия, которые будут проблемой.

0 голосов
/ 29 ноября 2018

Помощь была бы намного проще, если бы вы включили образец макета данных, которые вы пытаетесь проанализировать.Чтобы уточнить точки, которые вы не указали, насколько я понимаю,

  • "Полностью CSV с n заголовками, игнорируя все строки и округляя числа до совпадения со списком"Вы имеете в виду некоторый n столбец данных с k числовыми столбцами, каждый из которых описывает чей-то рост в дюймах.
  • Записи в числовых столбцах измеряются в футах.
  • Вы хотите игнорировать нечисловые столбцы и преобразовывать данные в 6.14 -> 6 feet, 1 inches (я неявно предполагаю, что при «округлении вниз» вы хотите получить целое число; то есть 6,14 фута)составляет 6 футов, 0,14 * 12 = 1,68 дюйма, решать вам, будет ли это пол или округлено до ближайшего целого числа).

Теперь для подмножества случайных высот, измеряемых в футах, отобранных равномерно на 5,1 фута и 6,9 фута, мы могли бы сделать следующее:

In [1]: import numpy as np

In [2]: import pandas as pd

In [3]: df = pd.DataFrame(np.random.uniform(5.1, 6.9, size=(10,3)))

In [4]: df
Out[4]:
      0         1         2
0  6.020613  6.315707  5.413499
1  5.942232  6.834540  6.761765
2  5.715405  6.162719  6.363224
3  6.416955  6.511843  5.512515
4  6.472462  5.789654  5.270047
5  6.370964  5.509568  6.113121
6  6.353790  6.466489  5.460961
7  6.526039  5.999284  6.617608
8  6.897215  6.016648  5.681619
9  6.886359  5.988068  5.575993

In [5]: np.fix(df) + np.floor(12*(df - np.fix(df)))/12
Out[5]:
      0         1         2
0  6.000000  6.250000  5.333333
1  5.916667  6.833333  6.750000
2  5.666667  6.083333  6.333333
3  6.416667  6.500000  5.500000
4  6.416667  5.750000  5.250000
5  6.333333  5.500000  6.083333
6  6.333333  6.416667  5.416667
7  6.500000  5.916667  6.583333
8  6.833333  6.000000  5.666667
9  6.833333  5.916667  5.500000

Мы используем np.fix, чтобы извлечь неотъемлемую часть значения высоты.Аналогично, df - np.fix(df) представляет дробный остаток в футах или дюймах при умножении на 12. np.floor просто усекает это до ближайшего дюйма ниже, а окончательное деление на 12 возвращает единицу измерения от дюймов до футов.

Вы можете изменить np.floor на np.round, чтобы получить ответ, округленный до ближайшего дюйма, а не урезанный до предыдущего целого дюйма.Наконец, вы можете указать точность вывода, чтобы настаивать на том, что десятичная часть выбрана из вашего списка.

In [6]: (np.fix(df) + np.round(12*(df - np.fix(df)))/12).round(2)
Out[6]:
  0     1     2
0  6.58  5.25  6.33
1  5.17  6.42  5.67
2  6.42  5.83  6.33
3  5.92  5.67  6.33
4  6.83  5.25  6.58
5  5.83  5.50  6.92
6  6.83  6.58  6.25
7  5.83  5.33  6.50
8  5.25  6.00  6.83
9  6.42  5.33  5.08
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...