簡體   English   中英

而不是在csv文件中丟失值,而是在該列中寫入平均值(在python中)

[英]Instead of missing values in the csv file, write the average of the values in that column(in python)

我想問的是,我有一個包含分類和數字值的csv文件。 此csv文件中缺少一些值。 我想計算此文件中每列的平均值,然后寫出我計算出的平均值,而不是該列中的缺失值。 我還使用pd.read_csv加載了必要的庫和文件。 即;

A B C D

 1,2,1,  

  ,1,,  

 2,1,1,2  

我想在上面的csv文件中的Cloumn A的第2行中寫入1,我將以相同的方式將其應用於其他列,因此我想要的csv表如下所示:

    A B C D  

    1,2,1,0.66  

    1,1,0.66,0.66  

    2,1,1,2  

例如,A列中有一個缺失值。我想寫我為A列計算的平均值,而不是A列中的此缺失值。(因此,由於(2 + 1)/ 3 = 1))。 我也想在其他列中應用此操作。我想以相同的方式將這些操作應用到其他列中。我試圖編寫代碼以在上面的代碼中執行此操作。 所以我試圖寫這段代碼:

    rows=list()
    column=list(myfile.columns.values)
    average = 0
    Sum = 0
    row_count = 1
    for row in myfile:
       for row in column:
           n = column
           Sum += n
           row_count += 1
    average = Sum / len(column)
    print('The average is:', average)  

該代碼無法正常工作。 如何實現此代碼,或者代碼完全錯誤?

由於格式錯誤,您的示例不清楚。 不用擔心,我在格式化方面也遇到了問題。 確定要使用熊貓嗎?

虛擬數據框。

df = pd.DataFrame(np.random.randn(50,4), columns=['A', 'B', 'C', 'D'])
df.iloc[2:4,0] = np.nan
df.iloc[3:5,1] = np.nan
df.iloc[4:6,2] = np.nan
df.iloc[5:7,3] = np.nan
df.head(10).round(2)

結果與

    A   B   C   D
0   -0.09   1.77    1.14    1.00
1   -1.24   -2.21   -0.21   -0.36
2   NaN -0.59   -0.77   -0.74
3   NaN NaN 0.37    -1.07
4   -0.19   NaN NaN 1.39
5   0.20    1.08    NaN NaN
6   -0.15   0.64    0.04    NaN
7   0.92    -1.01   1.81    -0.83
8   -0.79   0.13    -0.24   1.96
9   0.11    0.97    -0.97   -1.32

您使用以下方式加載數據框

df = pd.read_csv('path/to/your/file.csv')

另外,您的df中沒有NaN ,因此您可能要用NaN替換空單元格。

from numpy import nan
df.replace('', nan)

或替換這些列中的任何字符串

df.loc[:,'A':'D'].replace(r'\s+', nan, regex=True)

用按列均值填充nans:

df = df.apply(lambda x: x.fillna(x.mean()), axis=0)

用行均值填充nans:

df = df.apply(lambda x: x.fillna(x.mean()), axis=1)

那是您要找的東西嗎?

在OP編輯后進行編輯:

import pandas as pd
df = pd.DataFrame({
    'A': [1, '', 2],
    'B': [2, 1, 1],
    'C': [1, '', 1],
    'D': ['', '', 2]
})

def isnumber(x):
    try:
        float(x)
        return True
    except:
        return False

df = df[df.applymap(isnumber)]
df = df.apply(lambda x: x.fillna(x.mean()), axis=0)
df

是你所需要的全部。

產量

    A   B   C   D
0   1.0 2   1.0 2.0
1   1.5 1   1.0 2.0
2   2.0 1   1.0 2.0

我認為這是正確的答案。 具有NaN s的A列的平均值為(2 + 1) / 2 = 1.5因為您還沒有第三個值,因此無法將其計算在內。

您甚至不需要Pandas即可完成如此簡單的任務,內置的csv模塊已綽綽有余:

import csv

# on Python 3.x use: open("input.csv", "r")  
with open("input.csv", "rb") as f_in:  # open input.csv for reading
    r = csv.reader(f_in)  # create a CSV reader
    header = next(r)  # store the header to recreate in the output
    columns_num = len(header)  # max number of columns
    # read in rows and fill potentially missing elements with 0 to ensure a perfect 2D list
    rows = []  # a storage for our rows
    for row in r:  # go through each CSV row
        columns = []  # a storage for our columns
        for index in range(columns_num):  # loop through each column index
            try:
                columns.append(int(row[index]))  # convert to integer and store in `columns`
            except (IndexError, ValueError, TypeError):  # invalid column value
                columns.append(0)  # store 0 to `columns` as an 'empty' value
        rows.append(columns)  # store the processed columns to the `rows`  storage

total_rows = float(len(rows))  # a number to take into the account for average
rows = zip(*rows)  # flip the CSV columns and rows, on Python 3.x use: list(zip(*rows))
for i, row in enumerate(rows):
    average_real = sum(row) / total_rows  # calculate the real average
    average = int(average_real)  # integer average, use as an average for non-floats
    if average_real - average != 0:  # the average is not an integer
        average = int(average_real * 100) / 100.0  # shorten the float to 2 decimals
    rows[i] = [column or average for column in row]  # apply to empty fields and update

# on Python 3.x use: with open("output.csv", "w", newline='')
with open("output.csv", "wb") as f_out:  # open output.csv for writing
    writer = csv.writer(f_out)
    writer.writerow(header)  # write the header to output CSV
    writer.writerows(zip(*rows))  # flip back rows and colums and write them to output CSV

對於具有input.csv內容的input.csv文件:

A,B,C,D
1,2,1,
,1,,
2,1,1,2

它將產生output.csv為:

A,B,C,D
1,2,1,0.66
1,1,0.66,0.66
2,1,1,2

(注意:我已經修復了CSV標頭,使其成為有效的CSV,但即使它們沒有提供完美的2D列表(即,每行具有相同的列數),它也可以工作)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM