I want to do the same as F. Chollet's notebook but in C#.
However, I can't find a way to iterate over my KerasIterator object:
def extract_features(directory, sample_count):
features = np.zeros(shape=(sample_count, 4, 4, 512))
labels = np.zeros(shape=(sample_count))
generator = datagen.flow_from_directory(
directory,
target_size=(150, 150),
batch_size=20,
class_mode='binary'
)
i = 0
for inputs_batch, labels_batch in generator:
features_batch = conv_base.predict(inputs_batch)
features[i * 20 : (i + 1) * 20] = features_batch
labels[i * 20 : (i + 1) * 20] = labels_batch
i += 1
if i * 20 >= sample_count:
break
return features, labels
My current C# function is below.
Details:
foreach loop gives me a 'Compiler Error CS1579' on KerasIterator
for loop is not possible because a KerasIterator doesn't have a Length (or Size, etc.)
private List<NDarray> ExtractFeatures(ImageDataGenerator datagen, String directory, int sample_count)
{
// create the return NDarrays
NDarray features = np.zeros(shape: (sample_count, 4, 4, 512));
NDarray labels = np.zeros(shape: (sample_count, 4, 4, 512));
KerasIterator generator = datagen.FlowFromDirectory(
directory,
target_size: (150, 150).ToTuple(),
batch_size: 20,
class_mode: "binary"
);
int i = 0;
/* how do I iterate on 'generator' here, in a similar way than in Python? */
// return the List element
return new List<NDarray> { features, labels };
}
As of April 19. 2020 it is not possible with the .NET Wrapper as documented in this issue on the GitHub page for Keras.NET
Related
im trying to multiply each element in three different arrays by 2 with a loop but im having trouble. im really new at this so please excuse any obvious mistakes lol im not even sure ive im using the right kind of loop but heres what i have so far:
int[] firstArray = new int[] { 1, 2, 5, 6, 9 };
int[] secondArray = new int[] { 12, 3, 8, 20, 7 };
int[] thirdArray = new int[] { 2, 4, 6, 8, 10, 12 };
foreach(new int [5] in firstArray)
{
int newArray1= firstArray.Length * 2;
Console.WriteLine(newArray1);
}
i want it to print out the first new array as "2, 4, 10, 12, 18" in the console but when i run it, i get the error type and identifier are both required in a foreach statement.
any help would be greatly appreciated!
Do this with Linq
int[] resultFirstArray = firstArray.Select(r=> r * 2).ToArray();
int[] resultSecondArray = secondArray.Select(r=> r * 2).ToArray();
int[] resultThirdArray = thirdArray.Select(r=> r * 2).ToArray();
Or you can use Array.ConvertAll
Array.ConvertAll converts an entire array. It converts all elements in one array to another type.
var resultFirstArray = Array.ConvertAll(firstArray, x => 2 * x);
var resultSecondArray = Array.ConvertAll(secondArray, x => 2 * x);
var resultThirdArray = Array.ConvertAll(thirdArray, x => 2 * x);
If you just want to show the doubled values:
foreach(int value in firstArray)
{
Console.WriteLine(2 * value);
}
If you want to double the values in the array, then:
for(int i = 0 ; i < firstArray.Length ; i++)
{
firstArray[i] *= 2;
}
Then perhaps to show those values:
foreach(int value in firstArray)
{
Console.WriteLine(value);
}
If you want to create a new array with the values doubled:
var doubledArray = Array.ConvertAll(firstArray, x => 2 * x);
And to output those values:
foreach(int value in doubledArray)
{
Console.WriteLine(value);
}
I'm trying to reverse engineer a calculation that was done on an old program but can't quite get it. I need a count of how many values are in the top 27%, middle 46%, and bottom 27%.
I have the following data sets with eleven values in each and what the program yields in regards to the percentages and the number of values that fall into those percentiles.
Upper 27%: 4, Middle 46%: 4, Lower 27%: 3
values: 8,9,10,11,11,11,11,12,12,12,13
Upper 27%: 5, Middle 46%: 4, Lower 27%: 2
values: 2,3,4,4,4,4,5,5,5,5,5
Upper 27%: 2, Middle 46%: 8, Lower 27%: 1
values: 2,4,4,4,4,4,4,4,4,5,5
Upper 27%: 2, Middle 46%: 6, Lower 27%: 3
values: 13,17,17,18,19,19,19,21,21,23,24
I have found formulas such as (n * p) where n is the number of values and p is the percentile but it doesn't seem to work across all of these data sets to give the same results. I'm a little lost and haven't found anything that produces the results here.
I have tested code that I have found on the internet but none have worked on the different data sets.
Code sample that I tried:
internal static double percentile(double[] sortedData, double p)
{
if (p >= 100.0d) return sortedData[sortedData.Length - 1];
double position = (double)(sortedData.Length + 1) * p / 100.0;
double leftNumber = 0.0d, rightNumber = 0.0d;
double n = p / 100.0d * (sortedData.Length - 1) + 1.0d;
if (position >= 1)
{
leftNumber = sortedData[(int)System.Math.Floor(n) - 1];
rightNumber = sortedData[(int)System.Math.Floor(n)];
}
else
{
leftNumber = sortedData[0]; // first data
rightNumber = sortedData[1]; // first data
}
if (leftNumber == rightNumber)
return leftNumber;
else
{
double part = n - System.Math.Floor(n);
return leftNumber + part * (rightNumber - leftNumber);
}
}
Is there a formula or a name for what I am trying to do? Am I on the right track with percentile ranks?
You're on the right path. This is indeed the percentile rank formula. My initial thought was to get the value at the 27th percentile (which looking at your code it looks like you started down this path as well) and figure out how many values were greater than or less than; but the values you provided don't support these numbers very well.
Therefore the approach I took was to calculate the percentile rank of each number and put it into a count if they matched the percentile you have above. This seems to be the approach they took.
Formula (check out this website for more info):
PR% = L + ( 0.5 x S ) / N
Where,
L = Number of below rank,
S = Number of same rank,
N = Total numbers.
Code:
var lower = 0;
var middle = 0;
var upper = 0;
// var values = new int[] { 8, 9, 10, 11, 11, 11, 11, 12, 12, 12, 13 };
// var values = new int[] { 2, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5 };
// var values = new int[] { 2, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5 };
var values = new int[] { 13, 17, 17, 18, 19, 19, 19, 21, 21, 23, 24 };
var n = values.Length;
foreach(var i in values)
{
var pr = ((values.Count(v => v < i) + (.5 * values.Count(v => v == i))) / n);
if (pr < .27)
lower += 1;
else if (pr > .73)
upper += 1;
else
middle += 1;
}
Console.WriteLine("Upper: " + upper);
Console.WriteLine("Middle: " + middle);
Console.WriteLine("Lower: " + lower);
I am tasked to transform an Excel VBA to a web-based application. I am using Web Forms. I am stuck with a long Excel formula but I have converted half of the long formula into C#.
Here is the Excel formula:
IF(AND(D7="u", H7/F7>1), 0, INDEX(Scoring!$O$8:$O$10, SUMPRODUCT(--(E28 <= Scoring!$N8:$N10),--(E28 >= Scoring!$N8:$N10), ROW(INDIRECT("'Scoring'!$M1:$M3"))))
While here is my progress on the C# method. I need help on the ELSE part:
IF (variable = "u" && ((CurrentValue / AcceptedValue) > 1)){
return 0;
ELSE {
// the INDEX clause on the Excel Formula
}
O8 - O10 values are {2, 1, 0}
N8 - N10 values are {1, 1.5, 9999999999}
E28 is 0
I have also got the result of the remainder of the formula piece by piece. I just need guidance on how to put it in C#.
=INDEX(Scoring!$O$8:$O$10, SUMPRODUCT({1,1,1}, {0,0,0}, 1))
The double minus(--) made it return 0/1 instead of true/false. ROW(INDIRECT($M1-$M3)) is equivalent to 1.
I could use some help on transforming the Excel formula into C# code.
Here is some C# code to replicate this part of your formula:
INDEX(Scoring!$O$8:$O$10, SUMPRODUCT(--(E28 <= Scoring!$N8:$N10),--(E28 >= Scoring!$N8:$N10), ROW(INDIRECT("'Scoring'!$M1:$M3")))
In the code I've had to assign the array {1, 1, 1} for ROW(INDIRECT("'Scoring'!$M1:$M3")). There is some ambiguity in your question around the action of SUMPRODUCT. According to support.office.com
Multiplies corresponding components in the given arrays, and returns the sum of those products.
But some of your detail in the question makes me think you are thinking that each array get summed up and then those results get multiplied together. Anyway, check out the comments in the code below to follow the logic:
// inputs
double[] o8o10 = new double[] { 2, 1, 0 }; // Scoring!$O$8:$O$10
double[] n8n10 = new double[] { 1, 1.5, 9999999999 }; // Scoring!$N8:$N10
double e28 = 0; // E28
// entries to SUMPRODUCT
List<int> test1 = new List<int>();
List<int> test2 = new List<int>();
Array.ForEach(n8n10, x => { test1.Add((e28 <= x) ? 0 : 1); });
Array.ForEach(n8n10, x => { test2.Add((e28 >= x) ? 0 : 1); });
// ROW(INDIRECT("'Scoring'!$M1:$M3")) should be an array !
List<int> test3 = new List<int> { 1, 1, 1 };
// evalue SUMPRODUCT
int sumProductResult = 0;
for (var i=0; i<test1.Count; i++)
{
sumProductResult += test1[i] * test2[i] * test3[i];
}
// evalute INDEX
double indexResult = 0;
indexResult = o8o10[sumProductResult];
// output
Console.WriteLine(indexResult);
Console.ReadKey();
The output for me is 2 because that is the 0th element of the o8o10 array. We get 0 for the array index because
=SUMPRODUCT({1, 1, 1}, {0, 0, 0}, {1, 1, 1})
resolves to:
=SUM(1*0*1, 1*0*1, 1*0*1}
Which gives 0.
HTH
ROW(INDIRECT("'Scoring'!$M1:$M3")) actually evaluates to {1; 2; 3} and
--(E28 <= Scoring!$N8:$N10),--(E28 >= Scoring!$N8:$N10) is --(E28 = Scoring!$N8:$N10)
so the SUMPRODUCT formula is just:
(E28 = Scoring!$N8) * 1 + (E28 = Scoring!$N9) * 2 + (E28 = Scoring!$N10) * 3
and in C#:
double[] n8n10 = { 1, 2, 3 }; double e28 = 2;
double sumProduct = n8n10.Select((d, i) d == e28 ? i + 1 : 0).Sum();
But! because Scoring!$O$8:$O$10 is only 3 cells and the SUMPRODUCT can in theory result in more than 3, the actual aim of the INDEX SUMPRODUCT part seems to be something like this:
double[] o8o10 = { 4, 5, 6 }, n8n10 = { 1, 2, 3 };
double e28 = 2, result = o8o10[0]; // INDEX(array, 0) results in array
if (n8n10[1] == e28) result = o8o10[1];
else if (n8n10[2] == e28) result = o8o10[2];
List:
List<int> list1 = new List<int>(){ 0, 1, 2, 3, 4, 5, 6 };
let's say we want to reorder it. The beginning should be at number "2"
// 2,3,4,5,6,0,1
or at number 5
// 5,6,0,1,2,3,4
how do you do it with C#?
the reason: Imagine that you have an index of a given number in the List (number 3, index 3). You want to get the second number from the right - it'll be 5.
Unfortunately, if the starting number is at the end of the List (numbers 5 and 6) - out of range exception will be thrown, because there's no 7 and 8!
The idea is to reorder the List!
We enter Nr. 5 - we get 0 (5,6,0).
We enter Nr. 6 - we get 1 (6,0,1), etc.
or maybe there is some other (read - better) way to solve this problem?
The better way to do it is to use the mod operator %. This gives you the remainder when you divide an int by another int. The way this works is something like this:
int nextIndex = (currentIndex + offset) % length;
So, if your current index is 5, your offset is 2 and your length is 6 then:
5 + 2 = 7
7 / 6 = 1 remainder 1 (or 7 mod 6 = 1)
therefore nextIndex = 1
A little Linq can do this pretty easily:
List<int> list1 = new List<int>(new[] { 0, 1, 2, 3, 4, 5, 6 });
var numToStart = 4;
//reorderedList will be {4,5,6,0,1,2,3}
var reorderedList = list1.Skip(numToStart).Concat(list1.Take(numToStart));
You don't need to reorder the list. You could get the number with the following function:
int GetNumber(List<int> list, int fromValue, int index)
{
return list[(list.IndexOf(fromValue) + index) % list.Count()];
}
You could call the function like this:
List<int> list1 = new List<int>(new[] { 0, 1, 2, 3, 4, 5, 6 });
int number = GetNumber(list1, 5, 2); // number = 0
Mathematically we can solve it like Given Amount / Total Amount * 100 to get the percentage difference. But what I need is to compare 2 Integer Arrays (in C# Win App) and get the percentage of the difference.
Like :
1 -----> -2
2 -----> 3
3 -----> 7
4 -----> 456
5 -----> 13
These two columns are 2 Integer Arrays and I should get the difference between them.
How can I get this? A mathematical answer or an algorithm, whatever can be used to solve the problem.
try this
var i1 = Enumerable.Range(0, 10).ToArray();
var i2 = Enumerable.Range(20, 10).ToArray();
var result = i1.Select((n, i) => n * 100 / i2[i]);
What do you mean by difference? you can get the array of differences by:
int[] array = new int[arr1.Length];
for (i = 0; i < array.Length; i++)
{
array[i] = array1[i] - array2[i];
}
How about using LINQ:
Int32[] array1 = new Int32[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Int32[] array2 = new Int32[] { 9, 8, 7, 6, 5, 4, 3, 2, 1 };
Int32[] array3 = array1.Zip(array2, (a1, a2) => (a1 + a2) / 2).ToArray(); // Put whatever formula you want in there.
EDIT: Daniel and CD are correct. Code has been corrected. Thanks guys.
Thanks to everyone who replied to the question!
I thought about a solution these days but I'm not sure about the result. I have doubts about my work because I'm debugging it but each time with another 2 Arrays which contain more than 48.000 elements.
My solution so far was like :
for(int i=0;i<arr1.length;i++)
{
if(arr1[i] == arr2[i])
count++;
}
double percentage = (float)count / (float)arr1.length * 100;