dfarr1 Ответов: 1

Как я могу интерпретировать этот Python в C#?


Эй, ребята , я определенно не питон, но я парень C#. Могу ли я получить руку, пытаясь выяснить, как я могу воссоздать этот фрагмент кода в c#?

Фон:
У меня есть файл с разделителями табуляции, который содержит p-значение/критическое значение (для анализа хи-квадрат). Есть 9 столбцов данных. Первый столбец - это степени свободы, а последующие столбцы-критические значения в порядке p-значения. Заголовков нет, то есть данные начинаются с строки 0. Похоже, что у меня есть настроенный массив процентилей, и он используется при вычислении rx во фрагменте кода, а также позже, чтобы добавить дополнительный анализ статистики по сравнению с p-значениями в таблице и степенями свободы. Часто используется массив bs. Переменная in1 - это путь к перечисляемому файлу.

df=[]
	bs=[]
	percentiles=[[] for i in range(100)]
	for line_idx, line in enumerate(in1):
		cols = line.replace('\n', '').split('\t')		
		df.append(float(cols[0]))
		# bs.append(float(cols[1]))
		for j in range(9):
			percentiles[line_idx].append(float(cols[j+1]))
		rx=(percentiles[line_idx][2]+percentiles[line_idx][0]-2*percentiles[line_idx][1])/(percentiles[line_idx][2]-percentiles[line_idx][0])
		bs.append(rx)


Что я уже пробовал:

Я попытался настроить double [] [] test = double[100] []; и это было скомпилировано, когда я попытался перевести все напрямую, но получил много ошибок во время выполнения, ссылающихся на то, что вещи находятся вне индекса - я не верю, что было много положительного в этом методе.

Я также поместил файл хи-квадрат в таблицу данных, полагая, что это может быть полезно. Я не редактировал никаких данных. Я не могу сопоставить p-значения 1: 1, потому что они находятся в странных интервалах... Я смог определить значения Р 0,05 и 0,005, но все остальное колеблется между значением Р где-то около 0,99 и 0.

Jochen Arndt

Разделенный табуляцией файл очень похож на CSV-файл (CSV-файл с табуляцией в качестве разделительного символа). Таким образом, вы можете взглянуть на класс c# CSV reader, который поддерживает определение символа разделения.

dfarr1

Ну, на самом деле работать с csv и разделительным символом довольно просто - проблема в том, что под рукой находится фрагмент кода, который я просто не смог логически понять.

Jochen Arndt

Я не так тверд с питоном.

Но я не вижу причин использовать здесь массив 2-dim, потому что используется только текущий индекс строки (при условии, что массив процентилей больше не используется позже).

Код Python использует массив с размерами [100][10], но в показанном коде используются только правильные индексы от 0 до 2.

Так было бы и в с#:

double [,] процентиль = новый double[100, 10];

1 Ответов

Рейтинг:
7

Alberto Nuti

Это может быть хорошей отправной точкой:

var df = new List<float>();
var bs = new List<float>();
var percentiles = new List<float>[100];
for(int i = 0; i < percentiles.Length; i++)
{
    percentiles[i] = new List<float>();
}

var line_idx = 0;
foreach(var line in enumerate(in1))
{
    var cols = line.Replace(Environment.NewLine, "")
                   .Split(new[]{'\t'});
    df.Add(float.Parse(cols[0]));
    for(int j = 1; j < 9; j++)
    {
        percentiles[line_idx].Add(float.Parse(cols[j]));
    }
    
    var rx = (percentiles[line_idx][2] + percentiles[line_idx][0] - 2 * percentiles[line_idx][1])/(percentiles[line_idx][2]-percentiles[line_idx][0]);
    bs.Add(rx);
    line_idx++;
}


Я мог бы сделать какую-нибудь опечатку, так как это всего лишь небольшой фрагмент на лету.

Правка: Linq
var values = File.ReadLines("")
                .Select(line =>
                {
                    var cols = line.Replace(Environment.NewLine, "")
                                   .Split(new[] { '\t' })
                                   .Select(m => float.Parse(m))
                                   .ToArray();
                    return new
                    {
                        df = cols[0],
                        percentiles = cols.Skip(1).ToArray(),
                        bs = (cols[3] + cols[1] - 2 * cols[2]) / (cols[3] - cols[1])
                    };
                });
var df = values.Select(m => m.df).ToArray();
var bs = values.Select(m => m.bs).ToArray();
var percentiles = values.Select(m => m.percentiles).ToArray();


dfarr1

Отличный код, Альберто. Мне действительно пришлось немного подправить списки, но по большей части это было здорово. Вот с чем я пошел:
var df = new ArrayList();
var bs = new ArrayList();
ArrayList[] percentiles = new ArrayList[100];
for (int i = 0; i < percentiles.Length; i++)
{
percentiles[i] = new ArrayList();
}
var line_idx = 0;
foreach (var line in File.ReadLines(in1))
{
var cols = line.Replace(Environment.NewLine, "").Split(new[] { '\t' });
df.Add(float.Parse(cols[0]));
for (int j = 1; j < 9; j++)
{
percentiles[line_idx].Add(float.Parse(cols[j]));
}
var rx = (Convert.ToDouble(percentiles[line_idx][2]) + Convert.ToDouble(percentiles[line_idx][0]) - 2 *
Convert.ToDouble(percentiles[line_idx][1])) /
(Convert.ToDouble(percentiles[line_idx][2]) - Convert.ToDouble(percentiles[line_idx][0]));
bs.Add(rx);
line_idx++;
}

Alberto Nuti

У меня есть некоторые сомнения: пока ArrayList устарел и ведет себя так же, как List<object>, зачем их использовать? Вы тоже должны упаковывать\распаковывать значения! Если только вам не нужно ориентироваться на ".net framework < 2.0"...

Кроме того, как указал Йохен, лучшей реализацией должно быть "double [,] percentiles = new double[100, 10];".

Итак, список<поплавок&ГТ; оберткой вокруг массива чисел с плавающей точкой (типа float []), которые динамично росли, вы также можете использовать "список<список<поплавок&ГТ;&ГТ;(100)", а затем "процентили[я] = новый список<поплавок&ГТ;(10)", если вы действительно не хотите, чтобы справиться с двумя индексами (line_idx, и col_idx) а производительность должна быть действительно похожа на "старый стиль" сторону.

Наконец, если вы можете, вы определенно используете Linq:

var values = File.ReadLines("")
                .Select(line =>
                {
                    var cols = line.Replace(Environment.NewLine, "")
                                   .Split(new[] { '\t' })
                                   .Select(m => float.Parse(m))
                                   .ToArray();
                    return new
                    {
                        df = cols[0],
                        percentiles = cols.Skip(1).ToArray(),
                        bs = (cols[3] + cols[1] - 2 * cols[2]) / (cols[3] - cols[1])
                    };
                });
var df = values.Select(m => m.df).ToArray();
var bs = values.Select(m => m.bs).ToArray();
var percentiles = values.Select(m => m.percentiles).ToArray();