不要在csv文件中丢失值,而是在该列中写入值的平均值(用python)
我想问的是,我有一个csv文件,它由分类值和数字值组成。此csv文件中缺少一些值。我想计算此文件中每列的平均值,并写入我计算的平均值,而不是列中缺少的值。我还用pd.read_csv加载了必要的库和文件。即, A、B、C、D不要在csv文件中丢失值,而是在该列中写入值的平均值(用python),python,Python,我想问的是,我有一个csv文件,它由分类值和数字值组成。此csv文件中缺少一些值。我想计算此文件中每列的平均值,并写入我计算的平均值,而不是列中缺少的值。我还用pd.read_csv加载了必要的库和文件。即, A、B、C、D 1,2,1, ,1,, 2,1,1,2 我想将cloumn A第2行中的1写入如上所述的csv文件中。我将以相同的方式将其应用于其他列,因此我想得到的csv表如下所示: A B C D 1,2,1,0.66 1,
1,2,1,
,1,,
2,1,1,2
我想将cloumn A第2行中的1写入如上所述的csv文件中。我将以相同的方式将其应用于其他列,因此我想得到的csv表如下所示:
A B C D
1,2,1,0.66
1,1,0.66,0.66
2,1,1,2
例如,A列中缺少一个值。我想将为A列计算的平均值写入A列,而不是A列中缺少的值。(因此,由于(2+1)/3=1),我想将1写入A列的第二行)。我想在其他列中也应用这些操作。我想以同样的方式将这些操作应用到其他列。我尝试在上面的代码中编写代码来实现这一点。所以我试着写这段代码:
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)
用列式平均值填充NAN:
df = df.apply(lambda x: x.fillna(x.mean()), axis=0)
df = df.apply(lambda x: x.fillna(x.mean()), axis=1)
用行平均值填充NAN:
df = df.apply(lambda x: x.fillna(x.mean()), axis=0)
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
,因为您还没有第三个值,所以无法将其计算在内。您甚至不需要熊猫来完成如此简单的任务,内置的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
文件:
A,B,C,D
1,2,1,
,1,,
2,1,1,2
(注意:我已经修复了CSV标题,使其成为有效的CSV,但即使没有提供完美的2D列表,也能正常工作,即每行的列数相同)您在这里使用熊猫吗?
myfile.columns.values
看起来有点可疑……感谢您的关注。但是我没有准确地表达我自己,所以我编辑了我的问题。提前感谢您的帮助@TomWojcikHey,我对之前的回答做了修改。看看这是否是你想要的。谢谢你的帮助。你说得对。我不应该在平均值中添加缺失的值。谢谢您的回复。我只是想问这个。但是,当我将您提供的代码应用于文件时,我会遇到如下错误:回溯(最近一次调用last):文件“C:/Users/Pc/Desktop/Study/proje.py”,第125行,在header=next(r)#将要重新创建的头存储在输出中_csv。错误:迭代器应该返回字符串,而不是字节(您是在文本模式下打开文件的吗?)解决这个问题的方法是什么?@seyazc-您很可能在Python 3.x解释器上运行它。请看一下代码中的注释,这些注释指示您如何更改以使其与Python 3.x兼容。很抱歉占用您的时间。我纠正了你说的,问题就解决了。但是在代码中我得到了这样一个错误:文件“C:/Users/Pc/Desktop/Study/proje.py”,第130行,对于第+0行中的列=[[int(column或0)]*(columns-len(row)),对于r]文件“C:/Users/Pc/Desktop/Study/proje.py”,第130行,对于第+0行中的列=[[int(column或0)](columns-len(row))]对于r中的行]ValueError:int()的文本无效,基数为10:':'@seyazc-这是因为CSV中的某些字段具有无效值(:
,在本例中),无法转换为整数。我已更新了代码以处理此类问题(它将把任何非整数视为空值).谢谢你的帮助。