用平均值替换nan值

3
我希望使用Python将文本中每列缺失数据点替换为该列的均值。
我的想法是:
1.从文本文件中读取每一列 2.计算每列的平均值 3.用每列的计算平均值替换nan 4.将结果写回新的文本文件
我认为我能够完成前两个步骤,但在第三和第四步遇到了困难。以下是我的代码:
for columns in ( raw.strip().split() for raw in f ):
    a.append(columns[c])
    x = np.array(a, float)
    y = np.ma.masked_array(x,np.isnan(x))
    y1 = np.mean(y)
    a1 = ' '.join(a)
    a1.replace("nan", "y1")
    f1 = open("practice.txt", "w")
    f1.write(a1)

正如您所看到的,这里的问题涉及使用“替换”命令将nan替换为平均值,因为它只处理字符串。我将非常感谢任何帮助或建议。我的部分数据如下:

1.60566 nan 2.00755 2.32407
1.502   nan 1.36522 1.555
0.63333 nan 1.56102 2.08929
nan nan 0.87451 1.06667
2.5 nan 1.88889 1.0661
3.88197 nan 3.0875  2.75909
4.02692 nan 3.36154 3.92895
5.9907  nan 5.29535 5.82245
6.16111 2.67317 6.04074 6.25588
6.88269 2.62241 5.43958 6.07
5.92    2.48627 5.91818 6.75862
6.93429 6.17333 7.34    7.76538
8.25143 7.925   7.8087  8.725
8.1025  8.19429 8.11563 8.80937
8.12105 8.145   7.83889 8.37576
7.47292 8.65    8.35536 8.61081
8.10392 8.66032 8.74082 9.65484
10.03036    10.74727    10.634  10.50961

我希望能够用每一列的均值替换那些NaN值。


a1 是你代码中的一个字符串。 - Antimony
1
请问您能否展示一下需要解析的数据文件的部分内容? - chespinoza
是的,你说得对Antimony。我创建了一个字符串来使用“replace”,但它没有起作用。 - Isaac
3个回答

2

请记住,replace方法并不会直接替换原始字符串,你需要像这样做:

a1 = a1.replace("nan", str(y1))

1
@Isaac 没有问题!如果这个或其他回答对您有帮助,请考虑通过单击其左侧的复选标记接受它 - 这是您在 Stack Overflow 上说“谢谢”的方式 ;) - Óscar López
你有没有想过将结果字符串a1作为新文本文件中的列而不是行来编写? - Isaac
不可能在不知道列中的其余元素的情况下进行操作。你可以将整个表格(所有行和列)存储在一个矩阵中(一个子列表的列表,每个子列表代表一行),然后转置该矩阵并逐行输出结果。 - Óscar López

2
您可以使用掩码数组的填充方法(filled method):
import numpy as np

filename = '/tmp/data'
with open(filename, 'w') as f:
    f.write('''
1 2 nan
2 nan 3
nan 3 4
nan nan nan
''')

arr = np.genfromtxt(filename)
print(arr)
# [[  1.   2.  nan]
#  [  2.  nan   3.]
#  [ nan   3.   4.]
#  [ nan  nan  nan]]

mask = np.isnan(arr)
masked_arr = np.ma.masked_array(arr, mask)
means = np.mean(masked_arr, axis=0)

print(means)
# [1.5 2.5 3.5]

通过以上设置,

print(masked_arr.filled(means))

产量
[[ 1.   2.   3.5]
 [ 2.   2.5  3. ]
 [ 1.5  3.   4. ]
 [ 1.5  2.5  3.5]]

接下来,要将数组写入文件中,你可以使用np.savetxt

np.savetxt(filename, masked_arr.filled(means), fmt='%0.2f')

看起来非常有用!谢谢unutbu!我现在会尝试。 - Isaac
我有一个关于这个方法的问题。你似乎在f.write()中使用了字符串的行。我的文本文件中的字符串太大了。有没有办法在f.write()中使用我的整个文本文件数据? - Isaac
“f.write”只是用于在文件中创建一些数据。您已经有了文件中的数据。所以您可以跳过“f.write”的部分。您的数据是否太大,以至于“arr = np.genfromtxt(filename)”无法处理? - unutbu

2

你的问题是y1不是一个字符串吗?那么可以这样做:a1.replace("nan", str(y1))


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接