神经网络读取CSV文件时出现KeyError: 'close'列未找到求助
解决PyTorch数据读取时的KeyError: 'close'问题
报错信息
Traceback (most recent call last): File "C:\Users\zyman\AppData\Local\Programs\Python\Python39\lib\site-packages\pandas\core\indexes\base.py", line 3653, in get_loc return self._engine.get_loc(casted_key) File "pandas_libs\index.pyx", line 147, in pandas._libs.index.IndexEngine.get_loc File "pandas_libs\index.pyx", line 176, in pandas._libs.index.IndexEngine.get_loc File "pandas_libs\hashtable_class_helper.pxi", line 7080, in pandas._libs.hashtable.PyObjectHashTable.get_item File "pandas_libs\hashtable_class_helper.pxi", line 7088, in pandas._libs.hashtable.PyObjectHashTable.get_item KeyError: 'close'
复现代码
import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import Dataset, DataLoader import numpy as np import pandas as pd class Net(nn.Module): def __init__(self, input_size, hidden_size, output_size): super(Net, self).__init__() self.fc1 = nn.Linear(input_size, hidden_size) self.relu1 = nn.ReLU() self.fc2 = nn.Linear(hidden_size, hidden_size) self.relu2 = nn.ReLU() self.fc3 = nn.Linear(hidden_size, output_size) def forward(self, x): x = self.fc1(x) x = self.relu1(x) x = self.fc2(x) x = self.relu2(x) x = self.fc3(x) return x class CustomDataset(Dataset): def __init__(self, data_path, sequence_length): data = pd.read_csv(data_path, delimiter='\t') normalized_data = (data.iloc[:, :-1] - data.iloc[:, :-1].mean()) / data.iloc[:, :-1].std() self.inputs = [] self.targets = [] for i in range(len(data) - sequence_length - 1): self.inputs.append(normalized_data.iloc[i:i+sequence_length].values) close_price = data.iloc[i+sequence_length]['close'] open_price = data.iloc[i+sequence_length]['open'] if close_price > open_price: self.targets.append(1) # Green candle else: self.targets.append(0) # Red candle self.inputs = np.array(self.inputs) self.targets = np.array(self.targets) def __len__(self): return len(self.inputs) def __getitem__(self, index): return torch.tensor(self.inputs[index], dtype=torch.float32), torch.tensor(self.targets[index], dtype=torch.long) def train(model, dataset, num_generations, num_networks, num_clones, batch_size, num_epochs): for generation in range(num_generations): print(f"Generation: {generation + 1}") print("Training...") top_performers = [] for network_index in range(num_networks): print(f"Network: {network_index + 1}") model_clone = Net(input_size, hidden_size, output_size) model_clone.load_state_dict(model.state_dict()) dataset_size = len(dataset) train_size = int(0.8 * dataset_size) train_set, val_set = torch.utils.data.random_split(dataset, [train_size, dataset_size - train_size]) train_loader = DataLoader(train_set, batch_size=batch_size, shuffle=True) val_loader = DataLoader(val_set, batch_size=batch_size, shuffle=True) criterion = nn.BCEWithLogitsLoss() optimizer = optim.Adam(model_clone.parameters(), lr=learning_rate) best_val_accuracy = 0.0 for epoch in range(num_epochs): model_clone.train() for batch_inputs, batch_targets in train_loader: optimizer.zero_grad() outputs = model_clone(batch_inputs) loss = criterion(outputs.squeeze(), batch_targets) loss.backward() optimizer.step() model_clone.eval() correct_predictions = 0 total_predictions = 0 with torch.no_grad(): for val_inputs, val_targets in val_loader: val_outputs = model_clone(val_inputs) val_predictions = torch.round(torch.sigmoid(val_outputs)).squeeze() correct_predictions += (val_predictions == val_targets).sum().item() total_predictions += len(val_targets) val_accuracy = correct_predictions / total_predictions if val_accuracy > best_val_accuracy: best_val_accuracy = val_accuracy model.load_state_dict(model_clone.state_dict()) top_performers.append(model_clone) print("Evaluation...") correct_predictions = 0 total_predictions = 0 with torch.no_grad(): for inputs, targets in dataset: outputs = model(inputs.unsqueeze(0)) predictions = torch.round(torch.sigmoid(outputs)).squeeze() correct_predictions += (predictions == targets).sum().item() total_predictions += len(targets) accuracy = correct_predictions / total_predictions print(f"Accuracy: {accuracy * 100:.2f}%") if generation < num_generations - 1: top_performers = sorted(top_performers, key=lambda m: -best_val_accuracy)[:num_clones] model_clones = [Net(input_size, hidden_size, output_size) for _ in range(num_networks)] for i, performer in enumerate(top_performers): for j in range(num_clones): model_clones[i * num_clones + j].load_state_dict(performer.state_dict()) model = nn.Sequential(*model_clones) print("=" * 50) input_size = 5 hidden_size = 64 output_size = 1 learning_rate = 0.001 batch_size = 32 num_epochs = 10 sequence_length = 10 num_generations = 100 num_networks = 100 num_clones = 10 model = Net(input_size, hidden_size, output_size) dataset = CustomDataset('C:\\Users\\zyman\\PycharmProjects\\Pulling-Data\\NeuralNetworkTrainingData.csv', sequence_length) train(model, dataset, num_generations, num_networks, num_clones, batch_size, num_epochs)
问题分析
- 分隔符不匹配:代码中使用
delimiter='\t'读取CSV文件,但CSV文件默认以逗号作为分隔符,这会导致pandas将整行数据识别为单列,无法找到'close'列。 - 列名大小写不一致:文件列名是大写的
Close,但代码中使用小写的'close'进行索引,大小写不匹配直接触发KeyError。
解决步骤
修正文件读取分隔符:
将pd.read_csv(data_path, delimiter='\t')改为pd.read_csv(data_path)(CSV默认逗号分隔,若实际文件为其他分隔符可按需调整)。统一列名与索引的大小写:
两种可选方案:- 方案一:修改代码中的索引名称,将
'close'改为'Close','open'改为'Open'; - 方案二:读取文件时将所有列名转为小写,避免大小写问题:
data = pd.read_csv(data_path) data.columns = data.columns.str.lower()
- 方案一:修改代码中的索引名称,将
验证数据加载结果:
在读取文件后添加以下代码,确认列名和数据结构是否正确:print("文件列名:", data.columns) print("前5行数据:\n", data.head())
内容的提问来源于stack exchange,提问作者Žymantas Rastenis
相关产品推荐
相关产品推荐

