'ValueError: cannot set a row with mismatched columns' when adding a row to pandas DataFrame

'ValueError: cannot set a row with mismatched columns' when adding a row to pandas DataFrame

在学习 python 时,我决定尝试创建遗传算法,但卡在了变异步骤中。

对于解决此问题以及总体上代码的体系结构和风格的任何建议,我将很高兴。

one_generation = genlib.create_generation()
print(genlib.almost_generation(one_generation))

此代码return错误:

Traceback (most recent call last):
File "/home/rosrobot/PycharmProjects/gen2/main.py", line 23, in \<module\>
print(genlib.almost_generation(one_generation))

File "/home/rosrobot/PycharmProjects/gen2/genlib.py", line 83, in almost_generation
updated_generation.loc\[creature_index\] = sample\[updated_generation.columns\]

File "/home/rosrobot/PycharmProjects/gen2/venv/lib64/python3.10/site-packages/pandas/core/indexing.py", line 716, in __setitem__
iloc.\_setitem_with_indexer(indexer, value, self.name)

File "/home/rosrobot/PycharmProjects/gen2/venv/lib64/python3.10/site-packages/pandas/core/indexing.py", line 1682, in \_setitem_with_indexer
self.\_setitem_with_indexer_missing(indexer, value)

File "/home/rosrobot/PycharmProjects/gen2/venv/lib64/python3.10/site-packages/pandas/core/indexing.py", line 1998, in \_setitem_with_indexer_missing
raise ValueError("cannot set a row with mismatched columns")
ValueError: cannot set a row with mismatched columns

Process finished with exit code 1

'genlib' 文件中的函数:

import random as rnd
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns

pd.plotting.register_matplotlib_converters()

def create_creature(gen_length=10,
                    creature_name='one'):
    creature = pd.Series(data=[rnd.randint(0, 1) for i in range(gen_length)],
                         name=creature_name)
    return creature

def create_generation(generation_size=50,
                      gen_length=10):
    generation = pd.DataFrame(data=[create_creature(creature_name=(str(i + 1)) + 'th',
                                                    gen_length=gen_length) for i in range(generation_size)])
    generation['quality'] = generation.sum(axis=1)
    return generation

def __indexes_of_quality(generation):
    """
    :rtype: pd.Series
    """
    for i in generation.quality.unique():
        print('quality = ', i, ': ',
              generation.loc[generation.quality == i, 'quality'].index.values,
              '\n',
              '__')

def create_many_generations(number_of_generations=10,
                            generation_size=50,
                            gen_length=10):
    list_of_dataframes = pd.Series(data=[create_generation(generation_size=generation_size,
                                                           gen_length=gen_length
                                                           ) for i in range(number_of_generations)],
                                   name='creature_name')

    return list_of_dataframes

def one_generation_pyplot(generation):
    sns.barplot(x=generation.index,
                y=generation.sort_values('quality').quality)
    plt.show()

def many_generations_pyplot(list_of_generations):
    qualities = [sum(generation.quality) for generation in list_of_generations]
    sns.lineplot(data=qualities)
    plt.show()

def __mutation(creature: pd.Series) -> pd.Series:
    point = rnd.randint(0, len(creature))
    creature[point] = int(not creature[point].values)
    return creature

def almost_generation(generation):
    sample = generation.sample()
    sample = __mutation(sample)

    updated_generation = pd.DataFrame(columns=generation.columns)
    for creature_index in generation.index:
        if creature_index == sample.index:
            print(creature_index, ' == ', sample.index)
            updated_generation.loc[creature_index] = sample[updated_generation.columns]
        else:
            updated_generation.loc[creature_index] = generation.loc[creature_index]
    return updated_generation

我尝试将“示例”转换为 str,还尝试使用 locilocappend

在您的 almost generation 函数中,更改 if 块中的行以分配 values:

if creature_index == sample.index:
    print(creature_index, ' == ', sample.index)
    updated_generation.loc[creature_index] = sample[updated_generation.columns].values

您可以按如下方式简化整个函数:

def almost_generation(generation):
    sample = generation.sample()
    sample = __mutation(sample)
    generation.loc[sample.index] = sample[generation.columns].values
    return generation