Mean/median/mode from complex table in lua - lua

Thank you for all the support with lua, I'm very new and my application is working nicely so far.
I've made an app that will take in a few thousand numbers for different items. I'm trying to find the Mean/Media/Mode for each item, I've been able to do this for a single item, but not for all items.
Here is my table structure:
for i = 0, 1500 do
local e = {}
e.seller,
e.buyer,
e.itemName,
e.soldAmount = GetSoldAmount(FromMember(i))
table.insert(allSalesTempTable, e)
end
Table output format
[1] =
{
["itemName"] = [[Salad]]
["buyer"] = [[#Mike]],
["eventType"] = 15,
["soldAmount"] = 150,
["seller"] = [[#Sarah]],
},
[2] =
{
["itemName"] = [Pizza]
["buyer"] = [[#James]],
["eventType"] = 15,
["soldAmount"] = 150,
["seller"] = [[#Sarah]],
},
[3] =
{
["itemName"] = [Salad]
["buyer"] = [[#Frank]],
["eventType"] = 15,
["soldAmount"] = 75,
["seller"] = [[#Sarah]],
},
[4] ...
},
Then I'm trying to send the table/array to this mean function
stats={}
-- Get the mean value of a table
function stats.mean( t )
local sum = 0
local count= 0
local tempTbl = {}
(This is completely not going to work, but its what I'm trying so far)
for k,v in pairs(t) do tempTbl[k] = v
if v.itemName == tempTbl.itemName then
sum = sum + v.soldAmount
count = count + 1
end
end
return (sum / count)
end
--- To get the function started
stats.mean(e)
Here is where I'm getting fuzzy, Not sure if I can add the MEAN while collecting the data into the first temp table, or if it needs to be re-calculated after I have all the data?
If it needs to be done after, then my stats.mean(e) needs a way to insert it?
I'm trying to get this output:
[1] =
{
["itemName"] = [[Salad]]
["buyer"] = [[#Mike]],
["eventType"] = 15,
["soldAmount"] = 150,
["seller"] = [[#Sarah]],
["mean"] = 112.5 - New Insert somehow
},
[2] =
{
["itemName"] = [Pizza]
["buyer"] = [[#James]],
["eventType"] = 15,
["soldAmount"] = 150,
["seller"] = [[#Sarah]],
["mean"] = 150 - New Insert somehow
},
[3] =
{
["itemName"] = [Salad]
["buyer"] = [[#Frank]],
["eventType"] = 15,
["soldAmount"] = 75,
["seller"] = [[#Sarah]],
["mean"] = 112.5 - New Insert somehow
},
[4] ...
},
I've been working on this problem for a few days, After I see how to adjust my format for the mean and insert into the existing table I'll be able to figure out mean/min/max/median/mode easy enough.

Related

What is the problem with my Gradient Descent Algorithm or how its applied?

I've been trying figure out what I have done wrong for many hours, but just can't figure out. I've even looked at other basic Neural Network libraries to make sure that my gradient descent algorithms were correct, but it still isn't working.
I'm trying to teach it XOR but it outputs -
input (0 0) | 0.011441891321516094
input (1 0) | 0.6558508610135193
input (0 1) | 0.6558003273099053
input (1 1) | 0.6563021185296245
after 1000 trainings, so clearly there's something wrong.
The code is written in lua and I created the Neural Network from raw data so you can easily understand how the data is formatted.
- Training code -
math.randomseed(os.time())
local nn = require("NeuralNetwork")
local network = nn.newFromRawData({
["activationFunction"] = "sigmoid",
["learningRate"] = 0.3,
["net"] = {
[1] = {
[1] = {
["value"] = 0
},
[2] = {
["value"] = 0
}
},
[2] = {
[1] = {
["bias"] = 1,
["netInput"] = 0,
["value"] = 0,
["weights"] = {
[1] = 1,
[2] = 1
}
},
[2] = {
["bias"] = 1,
["netInput"] = 0,
["value"] = 0,
["weights"] = {
[1] = 1,
[2] = 1
}
},
[3] = {
["bias"] = 1,
["netInput"] = 0,
["value"] = 0,
["weights"] = {
[1] = 1,
[2] = 1
}
},
[4] = {
["bias"] = 1,
["netInput"] = 0,
["value"] = 0,
["weights"] = {
[1] = 1,
[2] = 1
}
}
},
[3] = {
[1] = {
["bias"] = 1,
["netInput"] = 0,
["value"] = 0,
["weights"] = {
[1] = 1,
[2] = 1,
[3] = 1,
[4] = 1
}
}
}
}
})
attempts = 1000
for i = 1,attempts do
network:backPropagate({0,0},{0})
network:backPropagate({1,0},{1})
network:backPropagate({0,1},{1})
network:backPropagate({1,1},{0})
end
print("Results:")
print("input (0 0) | "..network:feedForward({0,0})[1])
print("input (1 0) | "..network:feedForward({1,0})[1])
print("input (0 1) | "..network:feedForward({0,1})[1])
print("input (1 1) | "..network:feedForward({1,1})[1])
- Library -
local nn = {}
nn.__index = nn
nn.ActivationFunctions = {
sigmoid = function(x) return 1/(1+math.exp(-x/1)) end,
ReLu = function(x) return math.max(0, x) end,
}
nn.Derivatives = {
sigmoid = function(x) return x * (1 - x) end,
ReLu = function(x) return x > 0 and 1 or 0 end,
}
nn.CostFunctions = {
MSE = function(outputs, expected)
local sum = 0
for i = 1, #outputs do
sum += 1/2*(expected[i] - outputs[i])^2
end
return sum/#outputs
end,
}
function nn.new(inputs, outputs, hiddenLayers, neurons, learningRate, activationFunction)
local self = setmetatable({}, nn)
self.learningRate = learningRate or .3
self.activationFunction = activationFunction or "ReLu"
self.net = {}
local net = self.net
local layers = hiddenLayers+2
for i = 1, layers do
net[i] = {}
end
for i = 1, inputs do
net[1][i] = {value = 0}
end
for i = 2, layers-1 do
for x = 1, neurons do
net[i][x] = {netInput = 0, value = 0, bias = math.random()*2-1, weights = {}}
for z = 1, #net[i-1] do
net[i][x].weights[z] = math.random()*2-1
end
end
end
for i = 1, outputs do
net[layers][i] = {netInput = 0, value = 0, bias = math.random()*2-1, weights = {}}
for z = 1, #net[layers-1] do
net[layers][i].weights[z] = math.random()*2-1
end
end
return self
end
function nn.newFromRawData(data)
return setmetatable(data, nn)
end
function nn:feedForward(inputs)
local net = self.net
local activation = self.activationFunction
local layers = #net
local inputLayer = net[1]
local outputLayer = net[layers]
for i = 1, #inputLayer do
inputLayer[i].value = inputs[i]
end
for i = 2, layers do
local layer = net[i]
for x = 1, #layer do
local sum = layer[x].bias
for z = 1, #net[i-1] do
sum += net[i-1][z].value * layer[x].weights[z]
end
layer[x].netInput = sum
layer[x].value = nn.ActivationFunctions[activation](sum)
end
end
local outputs = {}
for i = 1, #outputLayer do
table.insert(outputs, outputLayer[i].value)
end
return outputs
end
function nn:backPropagate(inputs, expected)
local outputs = self:feedForward(inputs)
local net = self.net
local activation = self.activationFunction
local layers = #net
local lr = self.learningRate
local inputLayer = net[1]
local outputLayer = net[layers]
for i = 1, #outputLayer do
local delta = -(expected[i] - outputs[i]) * nn.Derivatives[activation](net[layers][i].value)
outputLayer[i].delta = delta
end
for i = layers-1, 2, -1 do
local layer = net[i]
local nextLayer = net[i+1]
for x = 1, #layer do
local delta = 0
for z = 1, #nextLayer do
delta += nextLayer[z].delta * nextLayer[z].weights[x]
end
layer[x].delta = delta * nn.Derivatives[activation](layer[x].value)
end
end
for i = 2, layers do
local lastLayer = net[i-1]
for x = 1, #net[i] do
net[i][x].bias -= lr * net[i][x].delta
for z = 1, #lastLayer do
net[i][x].weights[z] -= lr * net[i][x].delta * lastLayer[z].value
end
end
end
end
return nn
Any help would be highly appreciated, thanks!
All initial weights must be DIFFERENT numbers, otherwise backpropagation will not work. For example, you can replace 1 with math.random()
Increase number of attempts to 10000
With these modifications, your code works fine:
Results:
input (0 0) | 0.028138230938126
input (1 0) | 0.97809448578087
input (0 1) | 0.97785000216126
input (1 1) | 0.023128477689456

How to print a table's contents within a table? [Lua]

What I want to do is ONLY print a table's contents within a table. For example:
local stats = {
table1 = {
tTable1 =
{
data = 1
},
tTable2 =
{
data2 = 2
},
tTable3 =
{
data3 = 3
},
}
}
I don't really care about table1 or all the tTables but rather the information in the data variables. How can I print them?
This is a snippet of my real code:
local stats = {
[1] = {
[1] = {
[1] = 1,
[2] = -1,
[3] = -1,
["n"] = 3,
},
[2] = {
[1] = nuclearcraft:cooler,
[2] = 10,
["n"] = 2,
},
["n"] = 2,
},
[2] = {
[1] = {
[1] = 2,
[2] = -1,
[3] = -1,
["n"] = 3,
},
[2] = {
[1] = nuclearcraft:cell_block,
[2] = 0,
["n"] = 2,
},
["n"] = 2,
},
[3] = {
[1] = {
[1] = 3,
[2] = -1,
[3] = -1,
["n"] = 3,
},
[2] = {
[1] = nuclearcraft:cooler,
[2] = 10,
["n"] = 2,
},
["n"] = 2,
},
}
This code actually goes on for a bit longer than this. In the real code, I don't care for any of the data except for the areas where it says "nuclearcraft" and the number beneath it.
recursive table traversal is suitable for this case:
local function TablePrint(t)
for k,v in pairs(t) do
if type(v)=="table" then
print(k)
TablePrint(v)
else
print('\t',k,v)
end
end
end
TablePrint(stats)
result:
table1
tTable3
data3 3
tTable2
data2 2
tTable1
data 1
keep in mind that the order of non-index values in the table is not defined

Remove specific entry from Lua table

I am inserting into a table like this
Admin = {}
table.insert(Admins, {id = playerId, Count = 0})
And that works fine.
How do I remove that specific admin from that table now?
The following does not work, and Im sure its because ID is stored in an array that's inside of the table, but how would I access that then?
table.remove(Admins, playerId)
Basically,
I want to remove from the table Admins, where the ID == playerId that I input.
There are two approaches to remove an entry from the table, both are acceptable ways:
1. myTable[index] = nil Removes an entry from given index, but adds a hole in the table by maintaining the indices
local Admins = {}
table.insert(Admins, {id = 10, Count = 0})
table.insert(Admins, {id = 20, Count = 1})
table.insert(Admins, {id = 30, Count = 2})
table.insert(Admins, {id = 40, Count = 3})
local function removebyKey(tab, val)
for i, v in ipairs (tab) do
if (v.id == val) then
tab[i] = nil
end
end
end
-- Before
-- [1] = {['Count'] = 0, ['id'] = 10},
-- [2] = {['Count'] = 1, ['id'] = 20},
-- [3] = {['Count'] = 2, ['id'] = 30},
-- [4] = {['Count'] = 3, ['id'] = 40}}
removebyKey(Admins, 20)
-- After
-- [1] = {['Count'] = 0, ['id'] = 10},
-- [3] = {['Count'] = 2, ['id'] = 30},
-- [4] = {['Count'] = 3, ['id'] = 40}
2. table.remove(myTable, index)
Removes the entry from given index and renumbering the indices
local function getIndex(tab, val)
local index = nil
for i, v in ipairs (tab) do
if (v.id == val) then
index = i
end
end
return index
end
local idx = getIndex(Admins, 20) -- id = 20 found at idx = 2
if idx == nil then
print("Key does not exist")
else
table.remove(Admins, idx) -- remove Table[2] and shift remaining entries
end
-- Before is same as above
-- After entry is removed. Table indices are changed
-- [1] = {['id'] = 10, ['Count'] = 0},
-- [2] = {['id'] = 30, ['Count'] = 2},
-- [3] = {['id'] = 40, ['Count'] = 3}

Most optimized way to get value from table

I need to check if first value is >= 'from' and second value is <= 'to', if true then my function retun number. It's working but I don't know if this is the best and most optimized way to get value(number from table).
local table = {
{from = -1, to = 12483, number = 0},
{from = 12484, to = 31211, number = 1},
{from = 31212, to = 53057, number = 2},
{from = 53058, to = 90200, number = 3},
{from = 90201, to = 153341, number = 4},
{from = 153342, to = 443162, number = 5},
{from = 443163, to = 753380, number = 6},
{from = 753381, to = 1280747, number = 7},
{from = 1280748, to = 2689570, number = 8},
{from = 2689571, to = 6723927, number = 9},
{from = 6723928, to = 6723928, number = 10}
}
local exampleFromValue = 31244
local exampleToValue = 42057
local function getNumber()
local number = 0
for k, v in pairs(table) do
if (v.from and exampleFromValue >= v.from) and (v.to and exampleToValue <= v.to) then
number = v.number
break
end
end
return number
end
print(getNumber())
With this small amount of data, such function doesn't seem like a performace issue. However, you can compress the data a bit:
local t = {
12484, 31212, 53058, 90201, 153342, 443163, 753381, 1280748, 2689571, 6723928
}
local exampleFromValue = 31244
local exampleToValue = 42057
local function getNumber()
local last = -1
for i, v in ipairs(t) do
if exampleFromValue >= last and exampleToValue < v then
return i - 1
end
last = v
end
return 0
end

Lua. Attempt to index global "a" (a nil value)

I'm getting the following error:
Attempt to index global "a" (a nil value)
local gfx = love.graphics
return{
new = function( Image, Animation, Time)
return{
current_frame = 1,
current_anim = 1,
image = Image,
a = Animation,
play = false,
time = Time or 0,2,
counter = 0,
update = function(dt)
if play then
counter = counter + dt
if counter >= time then
counter = 0
current_frame = current_frame + 1
end
if current_frame > #a[current_anim] then
current_frame = 1
end
else
end
end,
play = function()
play = true
end,
stop = function()
play = false
end,
set_animation = function(anim)
if anim > #a then error("there is no animation ", anim) return end
current_anim = anim
end,
draw = function(data)
gfx.draw(image, a[current_anim][current_frame], data[1], data[2])
end
}
end
}
it seems to me, that I do give "a" a value - a table, containing a set of images, which I assign through second parameter.
-----
local quad = love.graphics.newQuad
local anim_data = {
quad(0,0, 32, 48, 192, 256),
quad(32,0, 32, 48, 192, 256),
quad(64,0, 32, 48, 192, 256),
quad(96,0, 32, 48, 192, 256),
quad(129,0, 32, 48, 192, 256),
quad(162,0, 32, 48, 192, 256)
}
local image = love.graphics.newImage("images/player_animation.png")
image:setFilter("nearest","nearest")
Here I supposedly give 'a' a value
animation = require("animations"):new(
image,
{
{ -- idle
anim_data[1]
},
{ -- walk
anim_data[2],
anim_data[3],
anim_data[4],
anim_data[5],
anim_data[6]
},
},
0.2
)
animation.play()
The a you are looking for is part of the table you are returning from the new function. It is not visible from the scope of those functions.
The easiest solution is to move the values you've placed in the table up in the scope of the new function, encapsulating them. However, this removes them from the table, so they won't be visible outside of the new, .play, .pause, .draw, .update, or .set_animation functions.
A better solution is to employ a more typical OOP solution, so I would suggest reading chapter 16 of Programming in Lua: Object-oriented Programming. Once you've read that chapter, go read every other just to be safe (particularly 5, 6, and 11).
local gfx = love.graphics
return {
new = function (Image, Animation, Time)
local current_frame = 1
local current_anim = 1
local image = Image
local a = Animation
local play = false
local time = Time or 0,2
local counter = 0
return {
update = function (dt)
if play then
counter = counter + dt
if counter >= time then
counter = 0
current_frame = current_frame + 1
end
if current_frame > #a[current_anim] then
current_frame = 1
end
end
end,
play = function ()
play = true
end,
stop = function ()
play = false
end,
set_animation = function (anim)
if anim > #a then
error("there is no animation ", anim)
return
end
current_anim = anim
end,
draw = function (data)
gfx.draw(image, a[current_anim][current_frame], data[1], data[2])
end
}
end
}

Resources